2010-08-08 134 views
4

是否有可能有一個類的對象返回真/假值,所以我可以做這樣的事情:如何從類對象返回值?

MyClass a; 
... 
if (a) 
    do_something(); 

我可以完成(幾乎)我想通過重載!運營商:

class MyClass { 
    ... 
    bool operator!() const { return !some_condition; }; 
    ... 
} 

main() 
    MyClass a; 
    ... 
    if (!a) 
     do_something_different(); 

,但我還沒有找到一種方法來重載這將是「空」操作符。當然,使用==運算符來檢查真/假也是可能的,事實上我到目前爲止一直在做這些事情。

回答

8

超載的void *的類型轉換操作符:

operator void *() const { return some_condition; }; 

這是怎麼流的工作,讓你說:

if (cin) { 
    // stream is OK 
} 

採用void *的,而不是布爾防止正在使用的投在某些情況下的錯誤,例如算術,在這種情況下是不可取的。除非你想在這些情況下使用它,當然。

+0

'bool'運算符比'void *'更具體。你能舉出一個涉及對bool進行投擲的錯誤示例嗎? – Dacav 2010-08-08 12:28:17

+0

謝謝。這工作得很好,除了我必須將some_condition投入(void *)之外。然而,每個人在這裏建議超載布爾(),也可以工作得很好,使代碼看起來更容易理解:)能否請您給的,事情可能出錯與解決方案的例子,這樣我就可以更好地理解的好處你的建議? – 2010-08-08 12:32:11

+2

@Dacav我不知道你的男人用更具體的 - 一個void *不能是算術表達式的一部分,這樣的類不能在形式'A + 1',這是我建議可以使用也可能不是OP想要。 – 2010-08-08 12:33:17

-1

嘗試過載(布爾)運算符:

operator bool() { /* ... */ } 
+0

壞主意,並不鼓勵。有關詳細信息,請參閱Neil的答案。 – 2010-08-08 12:37:57

+0

-1這會產生意想不到的副作用,請參閱安全布爾成語以獲得其他解決方案。 – 2010-08-08 12:48:19

6

顯而易見的解決方案 - 通過operator bool提供的隱式轉換到bool - 是一個壞主意。

這就是爲什麼如圖尼爾的回答標準庫使用operator void*

然而,值得指出的是,即使這個解決方案有缺陷,因此不再被認爲是安全的。不幸的是,想出更好的解決方案是不平凡的...

有在Artima描述safe bool idiom的文章了。對於一個真正的圖書館來說,這絕對是一條路,因爲它提供了最難以使用錯誤的最強大的界面。

+1

這也是最複雜的方法。值得一提的是,「我是否需要能夠直接在班級中使用班級?」只需提供一個'is_ok'成員函數,或者重載'operator()'返回一個bool,然後測試if(a())',可能會更簡單更明智。 – jalf 2010-08-08 13:13:20

+0

感謝您的鏈接,Konrad(和sbk)。這是非常有趣的閱讀,當然還有一些可供參考。 – 2010-08-08 13:19:53

+0

@jalf:是的,這就是爲什麼我添加了「對於真正的圖書館......」。關鍵是,對於圖書館來說,用戶的好處總是超過實現者的努力。一個難以使用和簡單的界面勝出,手下。 – 2010-08-08 17:39:49

5

奇怪,沒有人迄今已提到safe bool idiom。到目前爲止描述的所有其他解決方案都有缺點(您可能會也可能不關心),所有這些方法都在文章中描述。簡而言之,安全布爾成語如下所示:

class Testable { 
    typedef void (Testable::*bool_type)() const; 
    void this_type_does_not_support_comparisons() const {} 
    public: 
    operator bool_type() const { 
     return /* condition here */ ? 
     &Testable::this_type_does_not_support_comparisons // true value 
     : 0; // false value 
    } 
    }; 
+1

至少有一篇文章中描述的「問題」,刪除了void * cast的結果,有點令人懷疑。我使用的所有編譯器都至少給出了一個警告,因爲它是UB。 – 2010-08-08 12:59:28

+0

是的,我刪除了我的建議,因爲它存在誤導性缺陷。 如果你真的希望它在所有情況下都像一個bool一樣對待,那麼投射到布爾是完美的。鑄造無效*有其價值,但也有缺陷。這是一個通用的解決方案,如果它在所有情況下都應該被視爲布爾值,那麼選擇布爾就是最好的選擇。 – 2010-08-08 13:16:37

+1

AFAIK,在C++ 0x中,您將能夠標記轉換運算符**顯式**,不需要安全的布爾成語? – UncleBens 2010-08-08 13:44:03