在构造函数初始值设定项中初始化成员数组

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};

Questions

  1. 我怎样才能做我想做的事(那?) is, initialize an array in a 构造函数(不赋值元素) 这有可能吗?
  2. C + + 03标准对于在 ctor 初始化器中初始化聚合(包括数组)有什么特别说明吗?或者上述代码的无效性是其他一些规则的必然结果?
  3. C + + 0x 初始化器列表能解决这个问题吗?

P.S. 请不要提及向量、 ost: : 数组,以及它们对于数组的优越性,这一点我很清楚。

204003 次浏览
  1. 很不幸,没有。
  2. 你只是不能在你想要的方式,因为它不允许的语法(更下面)。您只能使用类似 ctor 的初始化,而且正如您所知,这对于初始化数组中的每个项目是不可用的。
  3. 我相信是这样的,因为它们以许多有用的方式全面推广了初始化。但我不确定细节。

在 C + + 03中,聚合初始化只适用于与下面类似的语法,它必须是一个单独的语句,不适用于 ctor 初始化器。

T var = {...};

解决办法:

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()) {}
};

C++98 doesn't provide a direct syntax for anything but zeroing (or for non-POD elements, value-initializing) the array. For that you just write C(): arr() {}.

我认为 Roger Pate 关于所谓的 C + + 0x 聚合初始化的限制是错误的,但是我懒得去查阅它或者检查它,而且这并不重要,不是吗?罗杰说的是“ C + + 03”,我把它误读成了“ C + + 0x”。抱歉,罗杰。

当前代码的一个 C + + 98解决方案是将数组包装在 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}};
  1. 我怎样才能做我想做的(即,在构造函数中初始化一个数组(而不是在主体中分配元素))。这有可能吗?

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

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

Mem-initializer 使用直接初始化。第八条规定禁止这种事。我不是很确定下面的情况,但是一些编译器允许这样做。

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

详情请参阅 this GCC PR

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

是的,没错。但我觉得你的语法是无效的。必须直接使用大括号才能启动列表初始化

struct A {
int foo[3];
A():foo{1, 2, 3} { }
A():foo({1, 2, 3}) { } /* invalid */
};

怎么样

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

?

Compiles fine on g++ 4.8

要在构造函数中初始化 int 数组吗? 请将其指向静态数组。

class C
{
public:
int *cArray;


};


C::C {
static int c_init[]{1,2,3};
cArray = c_init;
}

我发现这个问题非常有用,但是没有发现成员数组元素是一个没有缺省构造函数的对象和删除了复制/移动构造函数的例子。换句话说,这个示例初始化成员数组时没有进行不必要的对象复制。

例如,具有以下 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;
};

In-place initialization with non-default constructor would look like:

class B {
public:
A a[3];
B() : a { {1}, {2}, {3} } {}
};

这对我在 Windows 上使用 C + + 17很有效:

文件 A.h:

class A
{
private:
float arrayVar[3];
}

文件 A.cpp:

A::A() : arrayVar{ 0.0f, 0.0f, 0.0f } { }