2014-01-25 40 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成语*。 –