113
class C 
{
public:
 C() : arr({1,2,3}) //doesn't compile
{}
    /*
    C() : arr{1,2,3} //doesn't compile either
{}
    */
private:
 int arr[3];
};

我相信原因是数组只能用=语法初始化,即:

int arr[3] = {1,3,4};

问题

  1. 我该如何做我想做的事情(即在构造函数中初始化一个数组(而不是在主体中分配元素))。甚至可能吗?
  2. C++03 标准对在 ctor 初始化程序中初始化聚合(包括数组)有什么特别的说明吗?或者上述代码的无效是其他一些规则的必然结果?
  3. C++0x 初始化列表能解决问题吗?

PS请不要提及向量,boost::arrays,以及它们对数组的优越性,我很清楚。

4

7 回答 7

62
  1. 我该如何做我想做的事情(即在构造函数中初始化一个数组(而不是在主体中分配元素))。甚至可能吗?

是的。它使用包含数组的结构。你说你已经知道了,但是我不明白这个问题。这样,您可以在构造函数中初始化一个数组,而无需在主体中进行赋值。这就是这样boost::array做的。

C++03 标准对在 ctor 初始化程序中初始化聚合(包括数组)有什么特别的说明吗?或者上述代码的无效是其他一些规则的必然结果?

mem-initializer 使用直接初始化。第 8 条的规则禁止这种事情。我不太确定以下情况,但一些编译器确实允许这样做。

struct A {
  char foo[6];
  A():foo("hello") { } /* valid? */
};

有关详细信息,请参阅此 GCC PR

C++0x 初始化列表能解决问题吗?

是的,他们有。但是,我认为您的语法无效。您必须直接使用大括号来触发列表初始化

struct A {
  int foo[3];
  A():foo{1, 2, 3} { }
  A():foo({1, 2, 3}) { } /* invalid */
};
于 2010-10-30T09:33:17.140 回答
35

C++98 除了对数组进行归零(或对于非 POD 元素,值初始化)之外,不提供任何直接语法。为此,您只需编写C(): arr() {}.

我认为 Roger Pate 对 C++0x 聚合初始化的所谓限制是错误的,但我懒得查找或检查它,这没关系,不是吗?编辑:罗杰在谈论“C++03”,我把它误读为“C++0x”。对不起,罗杰。☺</p>

当前代码的 C++98 解决方法是将数组包装在 a 中struct并从该类型的静态常量初始化它。无论如何,数据必须驻留在某个地方。袖口它可以看起来像这样:

class C 
{
public:
    C() : arr( arrData ) {}

private:
     struct Arr{ int elem[3]; };
     Arr arr;
     static Arr const arrData;
};

C::Arr const C::arrData = {{1, 2, 3}};
于 2010-10-30T09:26:43.307 回答
9

解决方法:

template<class T, size_t N>
struct simple_array { // like std::array in C++0x
   T arr[N];
};


class C : private simple_array<int, 3> 
{
      static simple_array<int, 3> myarr() {
           simple_array<int, 3> arr = {1,2,3};
           return arr;
      }
public:
      C() : simple_array<int, 3>(myarr()) {}
};
于 2010-10-30T09:25:38.887 回答
4
  1. 不,不幸的是。
  2. 你只是不能以你想要的方式,因为它是不允许的语法(更多见下文)。您只能使用类似 ctor 的初始化,并且如您所知,这不适用于初始化数组中的每个项目。
  3. 我相信如此,因为他们以许多有用的方式全面概括了初始化。但我不确定细节。

在 C++03 中,聚合初始化仅适用于类似于以下的语法,它必须是单独的语句并且不适合 ctor 初始化程序。

T var = {...};
于 2010-10-30T08:56:09.487 回答
2

怎么样

...
  C() : arr{ {1,2,3} }
{}
...

?

在 g++ 4.8 上编译良好

于 2014-05-12T18:34:06.650 回答
2

我发现这个问题非常有用,但没有找到成员数组元素是没有默认构造函数和删除复制/移动构造函数的对象的例子。换句话说,在没有不必要的对象副本的情况下初始化成员数组的示例。

例如,具有以下 A 类:

class A {
  public:
    int v;
    A(int v) : v(v) { }
    A() = delete;
    A(A &&) = delete;
    A(const A &) = delete;
    A &operator =(A &&) = delete;
    A &operator =(const A &) = delete;
};

使用非默认构造函数的就地初始化如下所示:

class B {
  public:
    A a[3];
    B() : a { {1}, {2}, {3} } {}
};
于 2021-03-13T12:38:43.990 回答
-3

您想在构造函数中初始化一个整数数组吗?将其指向一个静态数组。

class C 
{
public:
    int *cArray;

};

C::C {
    static int c_init[]{1,2,3};
    cArray = c_init;
}
于 2017-06-29T09:37:38.177 回答