请考虑以下代码:
#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;
}
直到最近,我才认为标准和编译器“足够聪明”,足以在存在时找到所需的转换序列。
换句话说,我认为bool b2 = s
会将s
转换为first
,然后转换为bool
。但显然它没有发生。
获取first
和second
的等效行为的正确方法是什么?
答案 0 :(得分:3)
这是不可能的,因为只允许一个用户定义的转换:
4次标准转化[转化]
7 [注意:对于类类型,用户定义的转换被视为 好;见12.3。一般来说,隐式转换序列(13.3.3.1) 由标准转换序列和用户定义组成 转换后跟另一个标准转换序列。 - 结束 注意]
以及
12.3转化[class.conv]
4最多只有一个用户定义的转换(构造函数或转换函数)隐式应用于单个转换 值。
另见第5项(警惕用户定义的转换函数),28(智能指针)和30(更高效的C ++代理类)。
对于标准转换(使用内置类型),序列中可以进行的转换数量没有限制。
答案 1 :(得分:1)
您需要向operator bool
添加second
。编译器只会查看一个用户定义的隐式转换。