1

我有一个布局简单的结构,类似于:

struct A
{
   int a,b;
};

我在所有地方都使用了统一初始化来创建我的结构,例如:

A obj{2,3};

后来,我在 A 中添加了一个构造函数。它现在看起来像:

struct A
{
  int a,b;
  A(){}
};

这打破了统一初始化的使用。有没有一种简单的方法可以再次进行这项工作。也许通过使用默认关键字?

我希望有一些简单的东西来匹配我的简单结构。

4

5 回答 5

5

您的简单构造函数根本不执行任何操作(甚至不初始化aand b)。如果您打算初始化它们,为什么不做类似的事情

struct A {
    int a = 0, b = 0;
};

那样,

A x;
A y { 0 };
A z { 0, 0 };

所有的工作和初始化ab为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) { }
};

所有这些都将与统一初始化一起工作。

于 2013-11-11T20:58:11.950 回答
2

在这种情况下,您还应该声明一个带有两个参数的构造函数。例如

A( int a, int b ) : a( a ), b( b ) {}

或者您可以将默认构造函数声明为

A() = default; 

无需使用两个参数定义构造函数。

于 2013-11-11T20:59:39.230 回答
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};

如果类型是聚合,这可能是聚合初始化,或者如果类型有构造函数,它可能会调用构造函数。由于您使用统一初始化来初始化聚合,因此为了继续使用非聚合类型的语法,您只需定义一个适当的构造函数。

于 2013-11-11T21:22:18.110 回答
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}

于 2013-11-11T20:58:41.047 回答
0

实际上,您首先应该避免在聚合上使用 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);
}
于 2013-11-11T21:42:27.727 回答