假设我有这个功能:
void my_test()
{
A a1 = A_factory_func();
A a2(A_factory_func());
double b1 = 0.5;
double b2(0.5);
A c1;
A c2 = A();
A c3(A());
}
Run Code Online (Sandbox Code Playgroud)
在每个分组中,这些陈述是否相同?或者在某些初始化中是否有额外的(可能是可优化的)副本?
我见过有人说过这两件事.请引用文字作为证据.还请添加其他案例.
它只是偏好还是有特定的情况,其中一个是必要的而不是另一个?我正在参考以下变体进行初始化
T t(e); // direct initialization
T t = e; // copy initialization
Run Code Online (Sandbox Code Playgroud) c++ explicit-constructor implicit-conversion copy-initialization
在继续阅读本文之前,请阅读复制初始化和直接初始化之间的C++是否存在差异?首先,确保你理解它在说什么.
我先在这里总结一下规则(阅读标准n3225 8.5/16,13.3.1.3,13.3.1.4和13.3.1.5),
1)对于直接初始化,所有构造函数都将被视为重载集,重载决策将根据重载决策规则选择最佳构造函数.
2)对于复制初始化,源类型与目标类型相同或从目标类型派生,规则与上面相同,只是只转换构造函数(没有显式的构造函数)将被视为重载集.这实际上意味着显式复制/移动构造函数不会被视为重载集.
3)对于上面(2)中未包含的复制初始化情况(源类型与目标类型不同而不是从目标类型派生),我们首先考虑可以从源类型转换为目标类型的用户定义转换序列或(当使用转换函数时)到其派生类.如果转换成功,则结果用于指示初始化目标对象.
3.1)在这个用户定义的转换序列中,根据8.5/16和13.3.1.4中的规则,将考虑转换ctors(非显式ctors)和非显式转换函数.
3.2)结果prvalue将直接初始化目标对象,如(1)中列出的规则,见8.5/16.
好吧,对于规则来说,让我们看看一些奇怪的代码,我真的不知道我的推理错在哪里,或者只是所有编译器都错了.请帮帮我,谢谢.
struct A
{
A (int) { }
A() { }
explicit A(const A&) { }
};
struct B
{
operator A() { return 2; }
//1) visual c++ and clang passes this
//gcc 4.4.3 denies this, says no viable constructor available
};
int main()
{
B b;
A a = b;
//2) oops, all compilers deny this
}
Run Code Online (Sandbox Code Playgroud)
在我的理解中,对于(1),
operator A() { return 2; } …Run Code Online (Sandbox Code Playgroud)