我在C ++标准草案N4582中看到以下字眼:
[over.best.ics / 4]但是,如果目标是
(4.1)构造函数的第一个参数或
(4.2)用户定义的转换函数的隐式对象参数
并且构造函数或用户定义的转换函数是通过
(4.3)13.3.1.3,当参数是类copy-initialization的第二步中的临时变量时,或者
(4.4)13.3.1.4、13.3.1.5或13.3.1.6(在所有情况下),
不考虑用户定义的转换顺序。
我对粗体部分感到困惑,并且不知道该如何理解。我编写以下程序:
#include <iostream>
using namespace std;
struct A {
A(int) {}
operator int() {cout << "user-defined conversion" << endl; return 0;}
A(A&) {} //prevent default copy
};
int main()
{
A a = A(0);
}
它在g ++ 5.3.0中运行良好,并输出“用户定义的转换”,这意味着发生了用户定义的转换。当然,可以将其解释为临时A(0)不是复制初始化的结果。接下来,将程序更改为:
#include <iostream>
using namespace std;
struct A {
A(int) {}
operator int() {cout << "user-defined conversion" << endl; return 0;}
A(A&) {} //prevent default copy
};
A foo() {return A(0);}
int main()
{
A a = foo();
}
现在,foo()的值是从A(0)初始化的临时副本,但是程序仍然可以运行。为什么会这样?
您可以阅读[dcl.init] / 17了解实际的标准语言。这里的“第二步”是指A
从不b
相关类型的对象中复制初始化类类型的变量。在这种情况下,复制初始化分两个步骤进行:
b
为A
。如果为此调用转换构造函数,则它将创建一个临时A
。A
根据转换结果初始化变量。(在理智的课程中,通常会省略它。)那句话的意思是,在第二步中您不执行用户定义的转换。
例如,对于您A
,A a = 0;
。第一步,您从中创建了一个A
临时目录0
。在第二步中,您尝试a
使用该临时项进行初始化-不使用用户定义的转换。失败了,因为没有A
构造函数是可行的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句