0

私は「セーフブールイディオム」を指摘され、何が起こっているのかを解読しようとした後(サイトで提供された説明は、それが機能する理由を理解するのに十分ではありませんでした)、次のコードを試してみることにしましたできるだけ単純化しようとします。サイトは以下のコードを提供しました:

class Testable {
    bool ok_;
    typedef void (Testable::*bool_type)() const;
    void this_type_does_not_support_comparisons() const {}
  public:
    explicit Testable(bool b=true):ok_(b) {}

    operator bool_type() const {
      return ok_==true ? 
        &Testable::this_type_does_not_support_comparisons : 0;
    }
  };

「bool_type」の主な根拠を分析することにしました。これが中心になっているようです。次の行があるとします。

typedef void (Testable::*bool_type)() const;

bool_type が表す 'void Testable::*' の型の typedef であると推測することはできます (ブラケットのため、それほど簡単ではありません)。これは、次の変更と関数呼び出しを行うことでさらに実証できます。

class Testable {
    bool ok_;
    typedef void (Testable::*bool_type)() const;
    void this_type_does_not_support_comparisons() const {}
  public:
    explicit Testable(bool b=true):ok_(b) {}

    bool_type Test; //Added this

    operator bool_type() const {
      return ok_==true ?
        &Testable::this_type_does_not_support_comparisons : 0;
    }
  };

int main()
{
    Testable Test;
    int A = Test.Test; //Compiler will give a conversion error, telling us what type .Test is in the process
}

これにより、bool_type の型を確認できます。

エラー: 初期化で 'void (Testable::*)()const' を 'int' に変換できません

これは、実際に「void (Testable::*)」のタイプであることを示しています。

ここで問題が発生します。

次の関数を変更すると:

    operator bool_type() const {
      return ok_==true ? 
        &Testable::this_type_does_not_support_comparisons : 0;
    }

そしてそれを次のように変えます:

    operator void Testable::* () const //Same as bool_type, right? 
    {
      return ok_==true ? 
        &Testable::this_type_does_not_support_comparisons : 0;
    }

次の苦情が生成されます。

エラー: '*' トークンの前に識別子が必要です
エラー: '< 無効な演算子 >' が関数を返す関数として宣言されました

したがって、私の質問は次のとおりです。

'void (Testable::*) が実際に bool_type の typedef である場合、これらの苦情が生成されるのはなぜですか?

ここで何が起こっているのですか?

4

1 に答える 1

3

あなたの推論はここで間違っています

operator void Testable::* () const //Same as bool_type, right? 

これは正しくありません。bool_type の型は、コンパイラがエラー メッセージで通知するとおりです。

'void (Testable::*)()const'

したがって、オペレーターでそれを置き換えるには、次のようなものが必要になります

operator (void (Testable::*)() const) () const

それが可能なら!見苦しい typedef でさえ改善される理由がわかりますか?

C++11 にはexplicit operator bool()、この醜さから私たちを救うための新しい構造もあります。

于 2011-10-09T16:26:59.230 に答える