我正在使用 TR1 的 std::function
来实现一个简单的回调机制。如果我不想被回调,我将 nullptr
注册为回调处理程序。这编译并工作正常:
void Foo::MessageHandlingEnabled( bool enable ){
if( enable )
m_Bar.RegisterMessageHandler( std::bind(&Foo::BarMessageHandler, this, std::placeholders::_1) );
else
m_Bar.RegisterMessageHandler( nullptr );
}
如果我使用三元运算符重写它...
void Foo::MessageHandlingEnabled( bool enable ){
m_Bar.RegisterMessageHandler( enable?
std::bind(&Foo::BarMessageHandler, this, std::placeholders::_1) :
nullptr );
}
... VC++ 的编译器说:
error C2446: ':' : no conversion from 'nullptr' to 'std::tr1::_Bind<_Result_type,_Ret,_BindN>' 1> with 1>
[ 1> _Result_type=void, 1> _Ret=void, 1>
_BindN=std::tr1::_Bind2,Foo *,std::tr1::_Ph<1>> 1> ] 1> No constructor could take the source type, or constructor overload resolution was ambiguous
这是编译器的限制,还是我在做一些愚蠢的事情?我知道在这种特殊情况下,使用三元运算符可能不会给我带来任何好处,但我只是好奇。
最佳答案
三元运算符的两个分支必须返回相同类型的值,或者一个值的类型必须可以转换为另一个。
5.16.3 ... if the second and third operand have different types, and either has (possibly cv-qualified) class type, an attempt is made to convert each of those operands to the type of the other... [details omitted] Using this process, it is determined whether the second operand can be converted to match the third operand, and whether the third operand can be converted to match the second operand. If both can be converted, or one can be converted but the conversion is ambiguous, the program is ill-formed. If exactly one conversion is possible, that conversion is applied to the chosen operand and the converted operand is used in place of the original operand for the remainder of this section.
这就是编译器错误显示 ...no conversion from 'nullptr' to 'std::tr1::_Bind<_Result_type,_Ret,_BindN>' 1>...
的原因
nullptr
类型为 std::nullptr_t
和 std::function<>
有一个接受 std::nullptr_t
的构造函数. std::tr1::_Bind
无法转换为 std::nullptr_t
或者在三元运算符的上下文中反过来。
if/else
另一方面,根本不返回任何东西。
关于c++ - 为什么这里的三元运算符与 if-else 不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12840818/