对于原始类型,两者都是等价的,但对于用户定义的类类型,则存在差异。在这两种情况下,执行的代码都是相同的(在执行基本优化之后),但是如果我们初始化的元素不是我们正在构造的类型,则对类型的要求会有所不同。
复制初始化( T t = u;
) 等效于从T
已隐式转换为u
的临时类型的复制构造t
。另一方面,直接初始化等效于直接调用适当的构造函数。
虽然在大多数情况下没有区别,但如果声明了接受 的构造函数u
或explicit
复制构造函数不可访问,则复制初始化将失败:
struct A {
explicit A( int ) {}
};
struct B {
B( int ) {}
private:
B( B const & );
};
int main() {
A a(1); // ok
B b(1); // ok
// A a2 = 1; // error: cannot convert from int to A
// B b2 = 1; // error: B( B const & ) is not accessible
}
对于某些历史背景,最初的原始类型必须使用copy-initialization 进行初始化。当 *initializer-list*s 被添加到语言中以初始化类的成员属性时,决定原始类型应该使用与类相同的语法进行初始化,以保持初始化列表中的语法统一和简单。同时允许通过复制初始化来初始化类,使用户定义的类型更接近原始类型。两种初始化格式的区别自然而然:int a = 5.0;
被处理为从5.0
to的转换int
,然后a
从int
. 用户定义的类型也是如此:T u = v;
被处理为从v
to的转换T
,然后u
从该转换值复制构造。