2010-12-14 33 views
1

嗨,我已經衍生從C++安全布爾成語類我的類從這個頁面:The Safe Bool Idiom by Bjorn KarlssonC++安全布爾成語不能用Visual C++ 10(2010)編譯

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:類型元素「的條件表達式是非法。如果我嘗試將它轉換爲bool像下面,我得到這個錯誤

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

錯誤C2440:「類型轉換」:無法從「元素」到「布爾」轉換

這是第一次時間我正在使用安全的布爾成語,我不確定這是不是允許的或Visual C++ 10中的錯誤。任何評論?提前致謝!

+0

你有沒有試着用'類元素:公共safe_bool '?我知道這不完全是一回事,但是它與CRTP一起工作嗎? – 2010-12-14 12:54:25

+0

「class Element:public safe_bool 」不起作用。什麼是CRTP? – ShawnWong 2010-12-15 00:36:21

回答

1

的安全布爾成語是允許的,但我通常把它寫這樣的:

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以這種方式爲智能指針類(using an include file)實現了這個習語。

+0

我想這對我來說是一個壞主意,因爲在我的類中已經有一個運算符int()方法。元素是數據變體類。我正在放棄安全的bool習慣用法。感謝您的示例代碼! – ShawnWong 2010-12-15 00:40:22

+0

@ShawnWong:你試過看看它是否有效? typedef不必指向「int」 - 你可以指向*任何*數據成員。另外,首先有一個類似'operator int()'的轉換運算符通常不是最好的想法。 – 2010-12-15 01:01:19

0

它似乎沒有用任何編譯器編譯。顯然safe_bool無法返回其基地中受保護方法的地址。您應該添加一個公共方法到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; 
    } 
+0

我可以在文章中編譯代碼,只是當我在條件表達式中使用我的類時,它無法編譯。即使您的修改代碼生成「錯誤C2451:類型'元素'的條件表達式是非法的」 – ShawnWong 2010-12-15 00:34:10

相關問題