我有以下代码
class A {
private:
int n;
public:
A(int n) : n{n} {}
A(const A & a) : n{a.n} {}
};
class B {
private:
int m;
public:
B(int n) : m{n} {}
operator A() const { return A(m); }
operator int() const { return m; }
};
int main(int, char**)
{
B b{1};
(A)b; // Fails
static_cast<A>(b); // Fails
b.operator A(); // OK
}
这失败了
call of overloaded ‘A(B&)’ is ambiguous
(gcc,但 VC++ 和 clang 似乎以相同的方式处理它)
我原以为这三个都是完全一样的东西。使用 B 的运算符 A() 的转换。显然这不是正在发生的事情。为什么?
这个问题可以很容易地通过使 int() 运算符显式来解决,但我是在寻求解释而不是解决方案。
最佳答案
A
可以从 int
构建或 const A&
, B
可以转换为这两个,因此这些表达式是有歧义的,因为编译器无法知道这两个不同的路径是否创建了一些A
。来自B
导致相同的结果。
这是由于 static_cast
确定可能的转化路径的方法:
If a temporary object of type
new_type
can be declared and initialized with expression, as bynew_type Temp(expression);
, which may involve implicit conversions, a call to the constructor ofnew_type
or a call to a user-defined conversion operator, thenstatic_cast<type>(expression)
computes and returns the value of that temporary object. (ref)
注意这部分:
which may involve implicit conversions, a call to the constructor of
new_type
or a call to a user-defined conversion operator
你可以隐式转换B
至 int
, 然后构造 A
来自 int
.
或者您可以转换 B
至 A
根据转换运算符。
这就是使用 C 风格或 static_cast
时产生歧义的原因。在这里。
我建议构造函数 ( A(int)
) explicit
,而不是运营商。这通常是想要的行为。这将导致 static_cast<A>(b)
的明确行为: operator A()
被使用。
请注意 A a = b;
是明确的:它将使用 operator A()
, 因为隐式转换更喜欢用户定义的转换 ( ref )
关于c++ - 使用构造函数代替或类型转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26240357/