C++ 结合构造函数进行列表初始化
我有一个布局简单的结构,类似于: 结构A { INTA,b; }; 我已在各地使用统一初始化来创建我的结构,如:C++ 结合构造函数进行列表初始化,c++,c++11,list-initialization,C++,C++11,List Initialization,我有一个布局简单的结构,类似于: 结构A { INTA,b; }; 我已在各地使用统一初始化来创建我的结构,如: A obj{2,3}; 稍后,我在a中添加了一个构造函数。它现在看起来像: 结构A { INTA,b; A(){} }; 这打破了统一初始化的使用。有没有一种简单的方法可以让它再次发挥作用。也许使用默认关键字 我希望得到一些简单的东西,来匹配我的简单结构。您的简单构造函数什么都不做(甚至不初始化a和b)。如果您想初始化它们,为什么不执行以下操作 struct A { i
A obj{2,3};
稍后,我在a中添加了一个构造函数。它现在看起来像:
结构A
{
INTA,b;
A(){}
};
这打破了统一初始化的使用。有没有一种简单的方法可以让它再次发挥作用。也许使用默认关键字
我希望得到一些简单的东西,来匹配我的简单结构。您的简单构造函数什么都不做(甚至不初始化
a
和b
)。如果您想初始化它们,为什么不执行以下操作
struct A {
int a = 0, b = 0;
};
这样,
A x;
A y { 0 };
A z { 0, 0 };
所有工作并将a
和b
初始化为0
如果这对您不起作用,例如您有一个更复杂的构造函数,那么您可以使用如下委托构造函数:
struct A {
int a, b;
A() : A(0, 0) { }
A(int x) : A(x, 0) { }
A(int x, int y) : a(x), b(y) { }
};
或者更简单地说
struct A {
int a, b;
A(int x = 0, int y = 0) : a(x), b(y) { }
};
所有这些都将与统一的初始化一起工作。您的简单构造函数什么也不做(甚至不初始化
a
和b
)。如果您想初始化它们,为什么不执行以下操作
struct A {
int a = 0, b = 0;
};
这样,
A x;
A y { 0 };
A z { 0, 0 };
所有工作并将a
和b
初始化为0
如果这对您不起作用,例如您有一个更复杂的构造函数,那么您可以使用如下委托构造函数:
struct A {
int a, b;
A() : A(0, 0) { }
A(int x) : A(x, 0) { }
A(int x, int y) : a(x), b(y) { }
};
或者更简单地说
struct A {
int a, b;
A(int x = 0, int y = 0) : a(x), b(y) { }
};
所有这些都将与统一初始化一起使用。如果您使用的是C++11,则可以使用以下一个基本示例:
struct A{
int a, b;
A(initializer_list<int> ilist){
if (ilist.size() == 2){
a = *ilist.begin();
b = *ilist.begin() + 1;
}else //throw an exception
}
};
结构A{
INTA,b;
A(初始值设定项列表ilist){
如果(ilist.size()==2){
a=*ilist.begin();
b=*ilist.begin()+1;
}else//抛出异常
}
};
现在,可以像
A var={1,2}
一样初始化结构。如果您使用的是C++11,则可以使用以下基本示例:
struct A{
int a, b;
A(initializer_list<int> ilist){
if (ilist.size() == 2){
a = *ilist.begin();
b = *ilist.begin() + 1;
}else //throw an exception
}
};
结构A{
INTA,b;
A(初始值设定项列表ilist){
如果(ilist.size()==2){
a=*ilist.begin();
b=*ilist.begin()+1;
}else//抛出异常
}
};
现在可以像
A var={1,2}
一样初始化结构。在这种情况下,还应该声明一个具有两个参数的构造函数。比如说
A( int a, int b ) : a( a ), b( b ) {}
或者您可以将默认构造函数声明为
A() = default;
无需使用两个参数定义构造函数。在这种情况下,还应使用两个参数声明构造函数。比如说
A( int a, int b ) : a( a ), b( b ) {}
或者您可以将默认构造函数声明为
A() = default;
无需使用两个参数定义构造函数。没有构造函数的原始结构是聚合类型,因此允许使用聚合初始化。具有用户提供的构造函数的类型不是聚合,因此添加构造函数会中断聚合初始化的使用。事实上,声明该构造函数会导致它成为唯一的构造函数,并阻止您以该构造函数以外的任何方式初始化该类型的实例 为了拥有这样一个构造函数,并且能够以其他方式初始化该类型的实例,您必须用所需的行为声明其他构造函数。如果希望能够初始化a和b,可以执行以下操作:
struct A
{
int a,b;
A(){}
A(int a_, int b_) : a(a_), b(b_) {}
};
注意,我没有提到任何关于统一初始化的内容。以上任何一项都不依赖于统一初始化或C++11。统一初始化是用于初始化对象的特定语法 在C++03中,聚合初始化看起来只像:
S s = {1, 2};
在C++03中,使用构造函数看起来像:
S s(1, 2);
统一初始化引入了对不同类型的初始化使用相同语法的能力。即统一初始化可用于聚合初始化和通过构造函数初始化
因此,在C++11中,可以使用以下语法:
A a{1, 2};
如果类型是聚合,则这可能是聚合初始化;如果类型具有构造函数,则可能调用构造函数。由于您使用统一初始化来初始化聚合,为了继续对非聚合类型使用该语法,您只需定义一个适当的构造函数。没有构造函数的原始结构是聚合类型,因此允许您使用聚合初始化。具有用户提供的构造函数的类型不是聚合,因此添加构造函数会中断聚合初始化的使用。事实上,声明该构造函数会导致它成为唯一的构造函数,并阻止您以该构造函数以外的任何方式初始化该类型的实例 为了拥有这样一个构造函数,并且能够以其他方式初始化该类型的实例,您必须用所需的行为声明其他构造函数。如果希望能够初始化a和b,可以执行以下操作:
struct A
{
int a,b;
A(){}
A(int a_, int b_) : a(a_), b(b_) {}
};
注意,我没有提到任何关于统一初始化的内容。以上任何一项都不依赖于统一初始化或C++11。统一初始化是用于初始化对象的特定语法 在C++03中,聚合初始化看起来只像:
S s = {1, 2};
在C++03中,使用构造函数看起来像:
S s(1, 2);
统一初始化引入了对不同类型的初始化使用相同语法的能力。即统一初始化可用于聚合初始化和通过构造函数初始化
因此,在C++11中,可以使用以下语法:
A a{1, 2};
如果类型是聚合,则这可能是聚合初始化;如果类型具有构造函数,则可能调用构造函数。由于您使用统一初始化来初始化聚合,为了继续对非聚合类型使用该语法,您只需定义适当的构造函数。