我有一个布局简单的结构,类似于:
struct A
{
int a,b;
};
我在所有地方都使用了统一初始化来创建我的结构,例如:
A obj{2,3};
后来,我在 A 中添加了一个构造函数。它现在看起来像:
struct A
{
int a,b;
A(){}
};
这打破了统一初始化的使用。有没有一种简单的方法可以再次进行这项工作。也许通过使用默认关键字?
我希望有一些简单的东西来匹配我的简单结构。
我有一个布局简单的结构,类似于:
struct A
{
int a,b;
};
我在所有地方都使用了统一初始化来创建我的结构,例如:
A obj{2,3};
后来,我在 A 中添加了一个构造函数。它现在看起来像:
struct A
{
int a,b;
A(){}
};
这打破了统一初始化的使用。有没有一种简单的方法可以再次进行这项工作。也许通过使用默认关键字?
我希望有一些简单的东西来匹配我的简单结构。
您的简单构造函数根本不执行任何操作(甚至不初始化a
and 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( 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};
如果类型是聚合,这可能是聚合初始化,或者如果类型有构造函数,它可能会调用构造函数。由于您使用统一初始化来初始化聚合,因此为了继续使用非聚合类型的语法,您只需定义一个适当的构造函数。
如果您使用 C++11,则可以使用std::initializer_list
. 这是一个基本示例:
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 var = {1, 2}
实际上,您首先应该避免在聚合上使用 type{a, b} :
struct A
{
int a,b;
A() : a(0), b(0) {};
A(std::initializer_list<int> list) : a(*list.begin()), b(*(list.begin()+1)) {};
A(int x, int y) : a(0), b(0) { /* no arguments for a and b */ }
};
int main() {
int array[] = { 1, 2 };
A x{{1, 2}};
A y = {1, 2};
A z(1, 2);
}