2015-09-15 3 views
1

Я пытаюсь написать класс контейнера для векторной арифметики. Объекты являются статическими по величине:Как инициализировать класс типа std :: array

template<typename T, unsigned N> 
class vec{ 
    T data[N] = {0}; 
public: 
    vec(std::initializer_list<T> ini){ 
     std::copy(ini.begin(), ini.end(), data); 
    } 
} 

Вот как далеко я добрался.

Но чем я тестировал класс std :: array для сравнения, и я заметил, что он каким-то образом мог бы сделать статическое утверждение, если список инициализаторов был длинным или коротким.

std::array<float, 2> a = {1, 2, 3, 4} <- instant error message from the visual studio ide 

В моем классе мне пришлось бы проверять длину списка инициализаторов во время выполнения.

Я предполагаю, что класс std :: array каким-то образом управляет им, чтобы напрямую инициализировать данные с помощью нотации списка инициализаторов без класса std :: initializer_list.

Возможно ли инициализировать мой класс так же, как std :: array?

+0

Одна из причин, по которой ваш vec не позволит, это факт, что данные T [n] являются частными ... делают его общедоступным, а затем избавляются от конструктора. Кроме того, ваша примерная строка для std :: array выше компилируется, если вы включаете закрытие; – JVene

ответ

2

std::array является агрегатом, поэтому используется aggregate initialization. Предоставление избыточных элементов во время инициализации агрегата плохо сформировано и требует диагностики. Компилятор, как минимум, должен предоставить предупреждение, и gcc и clang делают это ошибкой. Поэтому, если вы сделаете свой класс агрегатом, вы можете заставить его работать так же, как это делает std :: array. Примечание: in class member initializers makes your class a non-aggregate в C++ 11, но не в C++ 14.

Мы можем видеть, что это агрегат, перейдя в проект C++ 11 стандартный раздел 23.3.2.1[array.overview]:

Массив представляет собой совокупность (8.5.1), который может быть инициализирован с помощью синтаксиса

array<T, N> a = { initializer-list }; 

, где инициализатор-список разделенных запятыми список до N элементов , чьи типы могут быть конвертированы в T.

и раздел 8.5.1[dcl.init.aggr] охватывает совокупный intialization и говорит:

Инициализатор-лист плохо формируется, если количество инициализатора-положений превышает число членов или элементы для инициализации.

Проект стандарта предусматривает экспозиции возможную реализацию которой сокращается до минимума выглядит следующим образом:

template <class T, size_t N> 
struct array { 
    T elems[N]; 
}; 

и проект стандарта имеет записку, в которой говорится:

Член Организации переменные элемы показаны только для изложения, чтобы подчеркнуть, что массив является агрегатом класса. Название elems не является частью интерфейса массива

, который представляет собой совокупность и как с GCC и звоном обеспечить ошибку, если предусмотрены избыточные элементы.

См. Также What are Aggregates and PODs and how/why are they special?.

Смежные вопросы