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

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以及它们对数组的优越性,我很清楚它们。

  1. 我怎么做我想做的事(即,在构造函数中初始化一个数组(不分配正文中的元素))。 这甚至有可能吗?

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

C ++ 03标准对ctor初始值设定项中的聚合(包括数组)初始化有什么特别之处吗? 或者上述代码的无效是其他规则的必然结果吗?

mem初始化器使用直接初始化。 而第8条的规定禁止这种事情。 我不确定下面的情况,但有些编译器确实允许。

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

看到这个GCC公关进一步的细节。

C ++ 0x初始化列表是否解决了这个问题?

是的,他们这样做。 但是,我认为你的语法是无效的。 您必须直接使用大括号来启动列表初始化

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

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

我的事情罗杰·皮特是错误的C ++ 0x聚合初始化的指称的限制,但我懒得查找或检查出来,没关系,是吗? 编辑 :罗杰是在谈论“C + + 03”,我误解为“C ++ 0x”。 对不起,罗杰。 ☺

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

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

解决方法:

 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()) {} }; 
  1. 不,不幸的是
  2. 你不能以你想要的方式,因为这是不允许的语法(下面更多)。 你只能使用类似ctor的初始化,正如你所知道的那样,它不可用于初始化数组中的每一项。
  3. 我相信是这样的,因为它们以许多有用的方式在整个主板上推广初始化。 但是我不确定细节。

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

 T var = {...}; 

怎么样

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

编译好g ++ 4.8

你想在你的构造函数中初始化一个int数组? 将其指向一个静态数组。

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