( expression-list )
:优先调用非聚合初始化,且会存在隐式转换= expression
:{ initializer-list }
:如果有聚合初始化(initializer_list<>),就调用聚合初始化,没有的话就调用符合条件的非聚合初始化= { initializer-list }
:同上- 使用
auto
声明的变量括号初始化,只允许一个参数的情况 {}
与()
调用构造函数初始化的方式,不同点在于{}
没有类型的隐式转换,比如 int x(1.2); 和 int x = 1.2; 通过隐式的对浮点值进行向下取整,然后将其转换为整型,从而将 x 的值初始化为 1。相反的, int x{1.2}; 将会遇到编译错误,初始化列表中的初始值,需要与变量声明的类型完全匹配。
测试代码一:
// #define AGGREGATE_INIT
class Test{
public:
Test(int a, float b, char* c){
cout << "int float char* initialize..." << endl;
}
Test(int a, int b, int c){
cout << "int int int initialize..." << endl;
}
Test(int a, double b, float c){
cout << "int double float initialize..." << endl;
}
#ifdef AGGREGATE_INIT
Test(initializer_list<int> ls){
cout << "initializer_list initialize..." << endl;
}
#endif
};
int main()
{
char cc[] = "abc";
Test t1{10, 1.2, cc}; // int float char* initialize...
Test t2{1, 2, 3}; // initializer_list initialize...
t2 = {4, 5, 6}; // initializer_list initialize...
// 如果存在聚合初始化构造会报错,此时只会匹配聚合初始化
// t2 = {4, 4.4, 4.f}; // error: narrowing conversion of ‘4.4000000000000004e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
// Test t3{4, 4.4, 4.f}; // error: narrowing conversion of ‘4.4000000000000004e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
// 如果不存在聚合初始化,会找匹配的非聚合初始化
t2 = {4, 4.4, 4.f}; // int double float initialize...
Test t3{4, 4.4, 4.f}; // int double float initialize...
Test t4(4, 4.4, 4.f); // int double float initialize...
t4 = {1, 2, cc}; // int float char* initialize...
return 0;
}
测试代码二:
template <typename T1, typename T2, typename T3>
class my_wrapper {
T1 t1;
T2 t2;
T3 t3;
public:
explicit my_wrapper(T1 t1_, T2 t2_, T3 t3_) : t1{t1_}, t2{t2_}, t3{t3_} {
cout << t1_ << " " << t2_ << " " << t3_ << endl;
}
};
// 工厂函数
template <typename T1, typename T2, typename T3>
my_wrapper<T1, T2, T3> make_wrapper(T1 t1, T2 t2, T3 t3) {
return my_wrapper{t1, t2, t3};
}
int main()
{
my_wrapper wrapper {123, 1.23, "abc"};
// my_wrapper<int, double, const char *> wrapper {123, 1.23, "abc"}; // 之前的写法
auto wrapper = make_wrapper(123, 1.23, "abc");
// auto wrapper = make_wrapper<int, double, const char *>(123, 1.23, "abc"); // 之前的写法
auto x{3};
// auto y{1,2}; // error: direct-list-initialization of ‘auto’ requires exactly one element [-fpermissive]
auto z = {1,2};
return 0;
}
参考: