构造函数重载选择强制转换操作符而不是结构类型

Yoc*_*mer 0 c++ constructor casting

我遇到了一个奇怪的情况,即编译器选择构建一个结构,即使有一个非常好的构造函数接收结构类型.
一个小例子:

struct A
{
    operator int() {return 1;}
};

struct B
{
    B(A& a) { OutputDebugStringA("A constructor\n"); }
    B(int i) { OutputDebugStringA("int constructor\n"); }
};
A test () { A a; return a;};

int _tmain(int argc, _TCHAR* argv[])
{
    B b(test());
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

说明:A具有int的强制转换运算符.B2个重载的构造函数,一个接受A引用,另一个接受int.
函数test()返回一个A对象.

由于某种原因,编译器决定将返回值强制转换为int,并使用接受int的构造函数. int constructor

谁能解释为什么会这样?我有一些理论,但我想要一个基于真实事物的答案(可能是标准的引用).

注意:
我可以通过将构造函数签名更改为:B(const A& a)或者 来获取预期结果(接受类型的构造函数) B(A&& a)

jua*_*nza 5

你的构造函数接受一个非const引用A,它不能绑定到临时引用.你在这里传递一个临时的:

 B b(test());
 //  ^^^^^^ temporary A
Run Code Online (Sandbox Code Playgroud)

所以唯一有效的构造函数就是那个int.您可以通过使相关构造函数获取const引用来更改此行为:

B(const A& a) { OutputDebugStringA("A constructor\n"); }
//^^^^^
Run Code Online (Sandbox Code Playgroud)

同样地,对于B(A&& a);在C++ 11.

或者,保持原始构造函数签名并传递左值也会导致构造函数调用:

A a;
B b(a);
Run Code Online (Sandbox Code Playgroud)