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


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


您是否还知道存在提供构造函数的boost固定大小数组?
贝诺

2
@Benoît:我是。但是我需要了解普通数组:)
Armen Tsirunyan 2010年

Answers:


55
  1. 我该怎么做我想做的事情(就是在构造函数中初始化一个数组(而不是在主体中分配元素))。可能吗?

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

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

内存初始化器使用直接初始化。并且第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 */
};

我在写这篇文章时偶然发现:char * const foo[6];类成员。它要求初始化程序在C ++ 11中进行编译。
JATothrim

33

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

我对Roger Pate关于C ++ 0x聚合初始化的所谓限制有错,但是我懒得查找或检查它,这没关系,对吗?编辑:罗杰(Roger)在谈论“ 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}};

我说0x有什么限制?

@Roger:“自动初始化...不适合于ctor初始化程序”。仅仅检查C ++ 0x N3126草案,第12.5.2 / 1节中的mem-initializer的语法包括使用braced -init-list
干杯和健康。-Alf 2010年

6
我的句子的前两个单词是C ++ 03,...

8

解决方法:

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

3
  1. 不,很不幸。
  2. 您只是无法按照自己的方式进行,因为语法不允许这样做(下文中有更多内容)。您只能使用类似ctor的初始化,并且,您知道,这不能用于初始化数组中的每个项目。
  3. 我相信,因为它们以许多有用的方式全面推广了初始化。但是我不确定细节。

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

T var = {...};


-2

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

class C 
{
public:
    int *cArray;

};

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

2
这是一个坏主意,因为如果您更改该数组,则该类的所有实例都会更改。
莫里
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.