三元运算符中的 Nullptr

Nullptr in ternary operator

本文关键字:Nullptr 运算符 三元      更新时间:2023-10-16

考虑:

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:"::没有从"A"到"nullptr"的转换(,而版本 B 可以编译?

(我知道我可以做例如

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

,我的问题是:为什么来自 nullptr 的构造显然与使用三元运算符的处理方式不同?

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

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

如果第二个和第三个操作数具有不同的类型,并且具有(可能符合 CV 标准(类类型,或者如果两者都是相同价值类别和相同类型,但简历资格除外,一个尝试将这些操作数中的每一个转换为其他。

否则(如果 E1 或 E2 具有非类类型,或者如果它们都具有类类型,但基础类不相同,也不相同另一个的基类(:如果 E1 可以转换为匹配 E2隐式转换为 E2 在应用后将具有的类型左值到右值 (4.1(、数组到指针 (4.2( 和函数到指针 (4.3( 标准转换。

A不能隐式转换为nullptrnullptr也不能隐式转换为A

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