Nullptr在三元运算符中

时间:2015-09-03 14:10:36

标签: c++

考虑:

struct A { bool operator==(const A& that) { return true; } };
boost::optional<A&> f()
{
    std::vector<A> vec;
    auto it = std::find(vec.begin(), vec.end(), A());

    // Version A
    return (it == vec.end() ? nullptr : *it);

    // Version B
    if (it == vec.end()) {
        return nullptr;
    } else {
        return *it;
    }
}

为什么版本A没有编译(错误C2446:&#39;:&#39;:没有从&#39; A&#39;转换为&#39; nullptr&#39;)而版本B呢?< / p>

(我知道我可以这样做。

return (it == vec.end() ? boost::optional<A&>() : *it);

,我的问题是:为什么nullptr的构造显然与三元运算符区别对待?)

仅在msvc12(= Visual Studio 2013)上测试。

1 个答案:

答案 0 :(得分:7)

标准5.16中的三元运算符规则

  

如果第二个和第三个操作数具有不同的类型,并且具有   (可能是cv-qualified)类类型,或者两者都是glvalues的类   相同的价值类别和相同的类型,除了cv-qualification,an   尝试将每个操作数转换为类型   其他

     

...

     

否则(如果E1或E2具有非类型,或者它们都具有   类类型,但底层类不一样,也不是   另一个的基类):如果E1可以,E1可以转换为匹配E2   被隐式转换为申请后E2所具有的类型   左值到右值(4.1),数组到指针(4.2)和   函数到指针(4.3)标准转换。

A无法隐式转换为nullptrnullptr无法隐式转换为A

编译第二个版本,因为从nullptroptional有一些隐式转换。