二阶隐式转换

Second order implicit conversion

考虑以下代码:

#include <iostream>

class first
{
    public:
        constexpr first(bool val) noexcept : _value{val} {}
        constexpr operator bool() const noexcept {return _value;}
    private:
        bool _value;
};

class second
{
    public:
        constexpr second(first val) noexcept : _value{val} {}
        constexpr operator first() const noexcept {return _value;}
    private:
        first _value;
};

int main(int argc, char** argv)
{
    first f{false};
    second s{true};
    bool b1 = f;
    bool b2 = s; // Not compiling 
    return 0;
}

直到最近,我一直认为标准和编译器 "clever" 足以在存在时找到所需的转换序列。

换句话说,我在想bool b2 = s会把s转换成first,然后再转换成bool。但显然它没有发生。

获得 firstsecond 等效行为的正确方法是什么?

您需要将 operator bool 添加到 second。编译器只会查看一个 user-defined 隐式转换。

这是不可能的,因为只允许一个 user-defined 转换:

4 Standard conversions [conv]

7 [ Note: For class types, user-defined conversions are considered as well; see 12.3. In general, an implicit conversion sequence (13.3.3.1) consists of a standard conversion sequence followed by a user-defined conversion followed by another standard conversion sequence. — end note ]

以及

12.3 Conversions [class.conv]

4 At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.

另请参阅更有效的 C++ 的第 5 条(警惕 user-defined 转换函数)、第 28 条(智能指针)和第 30 条(代理 类)。

对于标准转换(使用内置类型),序列中可以有多少转换没有限制。