Инициализация массива участника в инициализаторе конструктора

StackOverflow https://stackoverflow.com/questions/4057948

Вопрос

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 :: Armers и их превосходство к массивам, которые я хорошо знаю.

Это было полезно?

Решение

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

Другие советы

C ++ 98 не обеспечивает прямой синтаксис для чего-либо, кроме обнуления (или для элементов без стручки, инициализации значения). За то, что вы просто пишете 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}};

Обходной путь:

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

Вы хотите инициировать массив INTS в своем конструкторе? Укажите его на статический массив.

class C 
{
public:
    int *cArray;

};

C::C {
    static int c_init[]{1,2,3};
    cArray = c_init;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top