2014-01-25 41 views
0

我剛剛嘗試使用explicit operator bool()第一次,它的行爲對我來說是非常意外的。有人可以請說明爲什麼以下部分標有// does not work明確布爾操作符 - 不能返回,測試,初始化布爾

convertible類將例如,是一個智能指針類,能夠檢查包含數據的有效性。

struct convertible 
{ 
    explicit operator bool() const 
    { 
    return ptr; 
    } 

    void* ptr = nullptr; 
}; 

bool testReturn() 
{ 
    convertible test; 
    // does not work 
    return test; 
} 

bool testReturn2() 
{ 
    convertible test; 
    // does not work 
    return test == true; 
} 

bool testReturn3() 
{ 
    convertible test; 
    // works ?! 
    return !test; 
} 

int main() 
{ 
    convertible test; 
    // works 
    if (test) { } 
    // works 
    bool init(test); 
    bool tested = test; 
    bool tested2 = testReturn(); 
    bool tested3 = testReturn2(); 
    bool tested4 = testReturn3(); 
    return 0; 
} 

GCC的,我得到:

[email protected]:/tmp$ g++ --version 
g++ (GCC) 4.8.2 20131219 (prerelease) 
Copyright (C) 2013 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

[email protected]:/tmp$ g++ -std=c++11 test.cpp 
test.cpp: In function ‘bool testReturn()’: 
test.cpp:15:10: error: cannot convert ‘convertible’ to ‘bool’ in return 
    return test; 
     ^
test.cpp: In function ‘bool testReturn2()’: 
test.cpp:22:15: error: no match for ‘operator==’ (operand types are ‘convertible’ and ‘bool’) 
    return test == true; 
      ^
test.cpp:22:15: note: candidate is: 
test.cpp:22:15: note: operator==(int, int) <built-in> 
test.cpp:22:15: note: no known conversion for argument 1 from ‘convertible’ to ‘int’ 
test.cpp: In function ‘int main()’: 
test.cpp:39:17: error: cannot convert ‘convertible’ to ‘bool’ in initialization 
    bool tested = test; 

鏗鏘它類似於:

[email protected]:/tmp$ clang++ --version 
clang version 3.4 (tags/RELEASE_34/final) 
Target: x86_64-unknown-linux-gnu 
Thread model: posix 
[email protected]:/tmp$ clang++ -std=c++11 test.cpp 
test.cpp:15:10: error: no viable conversion from 'convertible' to 'bool' 
    return test; 
     ^~~~ 
test.cpp:22:15: error: invalid operands to binary expression ('convertible' and 'int') 
    return test == true; 
     ~~~~^~~~~ 
test.cpp:39:8: error: no viable conversion from 'convertible' to 'bool' 
    bool tested = test; 
    ^  ~~~~ 
3 errors generated. 

回答

2

如果你的目標是禁用某些轉換,只需通過delete符禁用它們:

struct convertible 
{ 
    operator bool() const //(Implicit) Conversion to bool allowed 
    { 
     return true; 
    } 

    operator int() const = delete; //Implicit/Explicit conversions to int disallowed 
            //(Results in compilation error). 
}; 


int main() 
{ 
    convertible c; 

    if(c) 
     ... 

    int a = c; //ERROR 
    int b = (int)c; //ERROR (The same for static_cast<int>(c)) 
} 

你也可以刪除所有對象,除了其正在使用的轉換操作符的模板版本明確重載:

struct foo 
{ 
    operator bool() const //Explicit overload for bool 
    { 
     return true; 
    } 

    template<typename T> 
    operator T() const = delete; //Everithing which is not a bool (Everithing which 
           //does not fit in the explicit overload) would 
           //resolve to this operator and will fail. 
}; 


int main() 
{ 
    foo f; 

    bool b = f; //OK 
    int i = f; //ERROR 
    char c = f; //ERROR 
    etc... 
} 
+0

太棒了 - 這正是我想要的!但奇怪的是,這仍然無法按預期工作:'foo f; f == true;'它顯然試圖在這裏用int來轉換? – milianw

+0

@milianw第一:不要寫像'if(f == true)'這樣的複合詞。只要寫'if(f)'。 '== true'是多餘的。 BTW'true'和'false'關鍵字被定義爲整數?大聲笑。只是不要寫'==真正' – Manu343726

+0

@milianw [我發佈了一個關於該主題的問題](http://stackoverflow.com/questions/21351450/implicit-conversion-to-boolean-and-comparison-with-布爾文字)。看起來像布爾比較被提升爲積分比較,所以在用戶定義的轉換與布爾比較的情況下,請求整數轉換。 – Manu343726

0

如果你的轉換運算符是explicit,你需要轉換它,像:

return static_cast<bool>(test); 
+0

是的,我知道這是明確的。我想禁止轉換爲除bool之外的任何內容 - 即將bool隱式轉換爲int,這是我期望看到禁止的。然而,轉換到布爾應該很好,不是嗎?換句話說:'bool a = convertible;'和'if(convertible)'有什麼區別 - 兩者都應該轉換爲bool就好了,不是嗎? – milianw

+0

比'static_cast'簡單一點可以是'bool(test)'。 @milianw:標準明確規定,當用作條件時,它將使用* explicit *轉換運算符。目的是在'istream'之類的東西中支持'explicit operator bool()const',而不是訴諸於舊的*安全的bool成語*。 –