我有一个简单布局的结构,类似于:
struct A
{
int a,b;
};
我在整个地方使用了统一初始化来创建我的结构,如:
A obj{2,3};
后来,我在A中添加了一个构造函数。它现在看起来像:
struct A
{
int a,b;
A(){}
};
这打破了统一初始化的使用。有没有一种简单的方法可以让这项工作重新开始。也许通过使用默认关键字?
我希望有一些简单的东西,以匹配我的简单结构。
答案 0 :(得分:5)
您的简单构造函数根本不执行任何操作(甚至不初始化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) { }
};
所有这些都适用于统一初始化。
答案 1 :(得分:2)
在这种情况下,您还应声明具有两个参数的构造函数。例如
A( int a, int b ) : a( a ), b( b ) {}
或者您可以将默认构造函数声明为
A() = default;
无需使用两个参数定义构造函数。
答案 2 :(得分: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};
如果类型是聚合,这可能是聚合初始化,或者如果类型具有构造函数,它可能会调用构造函数。由于您使用统一初始化来初始化聚合,因此为了继续使用非聚合类型的语法,您只需定义一个合适的构造函数。
答案 3 :(得分:0)
如果您使用的是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}
答案 4 :(得分:0)
实际上你应该首先避免在聚合上输入{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);
}