1

やあみんな、私はこのページのC++セーフブールイディオムクラスから私のクラスを派生させました:Bjorn Karlssonによるセーフブールイディオム

class Element : public safe_bool<>
{
public:
    bool Exists() const;
    // boolean_test() is a safe_bool method
    bool boolean_test() const { return Exists(); }; 
};

以下のようなif式で使ってみたところ

Element ele;
...
if(ele)

エラー C2451: conditional expression of type 'Element' is illegal が発生しました。以下のように bool にキャストしようとすると、このエラーが発生しました

Element ele;
...
if((bool)ele)

エラー C2440: '型キャスト': 'Element' から 'bool' に変換できません

安全な bool イディオムを使用するのはこれが初めてです。これが許可されていないのか、Visual C++ 10 のバグなのかわかりません。何かコメントはありますか? 前もって感謝します!

4

2 に答える 2

1

私は通常、次のように記述しますが、安全な bool イディオムは許可されています。

class Element
{
public:
    bool Exists() const;

    /* Begin Safe Bool Idiom */

private:
    // This is a typedef for pointer to an int member of Element.
    typedef int Element::*SafeBoolType;
public:
    inline operator SafeBoolType() const
        { return Exists() ? &Element::someDataMember : 0; }
    inline bool operator!() const
        { return !Exists(); }

    /* End Safe Bool Idiom */

private:
    int someDataMember; // Pick any data member
    // ...
};

これは私がそれを実装したのを見た方法です。実際、Boost はスマート ポインター クラスに対してこの方法で (インクルード ファイルを使用して) イディオムを実装します。

于 2010-12-14T12:54:07.947 に答える
0

どのコンパイラでもコンパイルできないようです。明らかsafe_boolに、保護されたメソッドのアドレスをそのベースで返すことはできません。public メソッドを追加してsafe_bool_base、そのアドレスを返す必要があります。

また、非依存構造を使用して演算子==とが無効になっているようです (インスタンス化されていなくてもエラーが発生する可能性があります)。!=

おそらくこれで問題が解決します:

 class safe_bool_base {
  protected:
    typedef void (safe_bool_base::*bool_type)() const;
  private:
    void cannot_compare_boolean_results() const {}
  public:
    void public_func() const {}
  protected:
    safe_bool_base() {}
    safe_bool_base(const safe_bool_base&) {}
    safe_bool_base& operator=(const safe_bool_base&) {return *this;}
    ~safe_bool_base() {}
  };

  template <typename T=void> class safe_bool : public safe_bool_base {
  public:
    operator bool_type() const {
      return (static_cast<const T*>(this))->boolean_test()
        ? &safe_bool_base::public_func : 0;
    }
  protected:
    ~safe_bool() {}
  };

  template<> class safe_bool<void> : public safe_bool_base {
  public:
    operator bool_type() const {
      return boolean_test()==true ? 
        &safe_bool_base::public_func : 0;
    }
  protected:
    virtual bool boolean_test() const=0;
    virtual ~safe_bool() {}
  };

  template <typename T, typename U> 
    bool operator==(const safe_bool<T>& lhs,const safe_bool<U>& rhs) {
      lhs.cannot_compare_boolean_results(); //call private method to produce error
      return false;
  }

  template <typename T,typename U> 
  bool operator!=(const safe_bool<T>& lhs,const safe_bool<U>& rhs) {
    lhs.cannot_compare_boolean_results(); //call private method to produce error
    return false;   
  }
于 2010-12-14T12:56:09.490 に答える