我遇到了一个问题,这对我来说很难解释。这是最小的,可重现的代码,它在GCC 6.2和Clang 3.9上都失败了:
class T2;
class T1
{
int field1;
public:
T1(int pf) : field1(pf) {}
operator int() { return field1; }
operator T2();
};
class T2
{
int field2;
public:
T2(int pf) : field2(pf) {}
};
T1::operator T2() { return T2(field1); }
void foo(T2 pt) {}
int main()
{
T1 obj1(1);
T2 obj2(2);
foo((T2) obj1); // ambiguous conversion for C-style cast from 'T1' to 'T2'
foo(T2(obj1)); // ambiguous conversion for functional-style cast from 'T1' to 'T2'
foo(static_cast<T2>(obj1)); // ambiguous conversion for static_cast from 'T1' to 'T2'
}
请注意,我没有编写特定的构造函数来从T1转换为T2,所以我想编译器应该都清楚,唯一的方法是使用用户定义的强制转换操作符。
奇怪的事实是,当我评论出一个看似无关的演员:
// operator int() { return field1; }
然后代码编译无忧无虑。这是什么原因?
答案 0 :(得分:3)
(T2) obj1
与T2(obj1)
(或本例中为static_cast<T2>(obj1)
)完全相同,但也许它更容易推理出类似构造函数的语法。< / p>
代码按原样,有两个选项:
T2
构建int
,由用户定义的转换运算符获取int
T2
构建T2
,由用户定义的转换运算符获取T2
根据N4140:
如果只有一个可行的功能比一个更好的功能 所有其他可行的功能,然后它是由重载选择的功能 解析度;这个电话是不正确的
两个相同形式的隐式转换序列 除非下列之一,否则无法区分转换序列 规则适用:
- 用户定义的转换序列
的第二个标准转换序列U1
是一个比其他用户定义的转换序列U2
更好的转换序列 包含相同的用户定义转换函数或构造函数或 他们在聚合初始化和初始化中初始化相同的类 无论哪种情况,U1
的第二标准转换序列都更好 比U2
。
由于这不适用,因此两种转换都不比另一种好。