unv*_*dim 21 c++ casting c++11
下面的代码在if语句中使用时会输出'operator bool',而在需要bool进行函数调用时会输出'operator void*'.
为什么它也不operator bool
用于函数调用?以及如何在两种情况下使用它?
#include <iostream>
class A
{
public:
explicit operator bool() const
{
std::cout << "operator bool" << std::endl;
return true;
}
operator void*() const
{
std::cout << "operator void*" << std::endl;
return 0;
}
};
void f(bool valid)
{
std::cout << "f called " << valid << std::endl;
}
int main(int argc, char *argv[])
{
A a;
if(a)
std::cout << "if a" << std::endl;
f(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Rak*_*111 21
在if
语句中,考虑隐式和显式转换运算符.因为A
有一个operator bool
,它选择那个,因为它比转换A
为a void*
然后将其转换为更好的匹配bool
.
但是在其他语句中,不是条件(if
,while
...),显式转换运算符不参与重载解析,而且唯一有效的运算符则operator void*
可以使用,因为存在从指针到指针的隐式转换bool
.
如果你想operator bool
被选中,你需要将其设为非explicit
,或者使用强制转换(因为这就是标记它的explicit
含义,确保必须明确使用它):
f(static_cast<bool>(a));
Run Code Online (Sandbox Code Playgroud)
原因是使用函数说明符声明了运算符explicit
.
在if语句的条件下,该值在上下文中转换为bool类型.
来自C++标准(4个标准转换)
2 [注意:具有给定类型的表达式将在多个上下文中隐式转换为其他类型:
...
- 在if语句或迭代语句(6.4,6.5)的条件下使用时.目的地类型是bool.
但是,当值作为参数传递给函数时,会使用所谓的复制初始化.在这种情况下,函数说明符显式阻止转换为bool类型.
来自C++标准(12.3.2转换函数)
2 转换函数可以是显式的(7.1.2),在这种情况下,它仅被视为用户定义的直接初始化转换 (8.5).否则,用户定义的转换不限于在分配和初始化中使用.
强制调用bool运算符的一种简单方法如下
f( bool( a ) );
Run Code Online (Sandbox Code Playgroud)