为什么三元运算符与if-else在这里不一样?

dar*_*mos 0 c++ visual-studio-2010 nullptr c++11 std-function

我正在使用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 );
}
Run Code Online (Sandbox Code Playgroud)

如果我使用三元运算符重写它...

void Foo::MessageHandlingEnabled( bool enable ){
        m_Bar.RegisterMessageHandler( enable?
                                      std::bind(&Foo::BarMessageHandler, this, std::placeholders::_1) :
                                      nullptr );   

 }
Run Code Online (Sandbox Code Playgroud)

... VC++的编译器说:

错误C2446:':':没有从'nullptr'转换为'std :: tr1 :: _ Bind <_Result_type,_Ret,_BindN>'1> 1>
[1> _Result_type = void,1> _Ret = void,1>
_BindN = std :: tr1 :: _ Bind2,Foo*,std :: tr1 :: _ Ph <1 >> 1>] 1>没有构造函数可以采用源类型,或者构造函数重载解析是模糊的

这是编译器的限制,还是我做了一些愚蠢的事情?我知道在这种特殊情况下,使用三元运算符可能无法获得任何好处,但我只是好奇.

Max*_*kin 7

三元运算符的两个分支必须返回相同类型的值,或者一个值的类型必须可以转换为另一个.

5.16.3 ...如果第二个和第三个操作数具有不同的类型,并且具有(可能是cv限定的)类类型,则尝试将每个操作数转换为另一个操作数的类型... [详细信息省略使用该过程,确定是否可以转换第二操作数以匹配第三操作数,以及是否可以转换第三操作数以匹配第二操作数.如果两者都可以转换,或者一个可以转换,但转换不明确,则程序格式不正确.如果只能进行一次转换,则将该转换应用于所选操作数,并使用转换后的操作数代替本节其余部分的原始操作数.

这就是编译器错误所说的原因 ...no conversion from 'nullptr' to 'std::tr1::_Bind<_Result_type,_Ret,_BindN>' 1>...

nullptr具有类型,std::nullptr_tstd::function<>具有接受的构造函数std::nullptr_t.std::tr1::_Bind不能std::nullptr_t在三元运算符的上下文中转换为或相反.

if/else 另一方面,根本不返回任何东西.