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



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. как я могу сделать то, что я хочу сделать (что
    есть инициализации массив в a
    конструктор (не присваивая элементы
    в теле.)) Это вообще возможно?

  2. стандарт C++03 говорит что-нибудь особенное об инициализации агрегатов (включая массивы) в инициализаторах ctor? Или недействительность вышеуказанного код является следствием некоторых других правил?

  3. списки инициализаторов C++0x решают проблему?


П. С. пожалуйста, не упоминайте векторы, boost::arrays и их превосходство над массивами, о которых я хорошо знаю.

639   6  

6 ответов:

  1. как я могу сделать то, что я хочу сделать (то есть, инициализировать массив в конструкторе (не назначая элементы в теле)). Это вообще возможно?

да. Он использует структуру, которая содержит массив. Вы говорите, что уже знаете об этом, но тогда я не понимаю вопроса. Таким образом, вы do инициализировать массив в конструкторе, без назначения в теле. Вот что boost::array делает.

стандарт C++03 говорит что-нибудь особенное об инициализации агрегатов (включая массивы) в инициализаторах ctor? Или недействительность вышеуказанного кодекса является следствием некоторых других правил?

mem-инициализатор использует прямую инициализацию. И правила статьи 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 не предоставляет прямого синтаксиса ни для чего, кроме обнуления (или для не-POD элементов, инициализации значений) массива. Для этого вы просто пишете C(): arr() {}.

Я думаю, что Роджер Пэйт ошибается в предполагаемых ограничениях инициализации агрегата C++0x, но я слишком ленив, чтобы искать или проверять его, и это не имеет значения, не так ли? EDIT: Роджер говорил о "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;
}

Comments

    Ничего не найдено.