2016-07-07 5 views
3

Итак, давайте предположим, у меня есть следующий класскласса с станд :: массив объектов без конструкторов по умолчанию

class NoDefaultConstructor { 
    NoDefaultConstructor() = delete; 
    ... 
}; 

И у меня есть еще один класс, который имеет массив типа NoDefaultConstructor и других членов

class Wrapper { 
    std::array<NoDefaultConstructor, 2> arr; 
    ... 
}; 

Как инициализировать массив в конструкторе для Wrapper (возможно, в списке инициализаторов с использованием std::intializer_list)?

В частности, это единственный способ передать аргументы конструктору массива в списке инициализаторов для Wrapper, чтобы иметь конструкцию, аналогичную следующей: Я думал об этом, потому что размер массива может измениться в будущем.

template <typename... Values> 
Wrapper(Values&&... values) : arr{std::forward<Values>(values)...} {} 
+0

Вы можете хранить 'станд :: unique_ptr ' экземпляры в массиве вместо просто 'NoDefaultConstructor'. – ArchbishopOfBanterbury

+0

Я исследовал эту идею, но я не хотел ее использовать, потому что вместо этого я мог бы использовать 'std :: vector' – Curious

+0

Поиск вопросов о том, как инициализировать элементы данных без конструкторов по умолчанию. Их много. – juanchopanza

ответ

6

std::array обязательный быть заполнителем. Поэтому он не имеет нетривиальных конструкторов, но может быть инициализирован с использованием агрегатной инициализации. Обратите внимание, что агрегатная инициализация включает в себя список braced-init-list (то есть список инициализаторов, заключенный в скобки), но не объект std::initializer_list.

class Wrapper { 
    public: 
    Wrapper() : arr {MakeNoDefaultConstructor(123), 
        MakeNoDefaultConstructor(456)} {} 
    //    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ braced-init-list 
    private: 
    std::array<NoDefaultConstructor, 2> arr; 
}; 

EDIT Конструктор с переменным числом аргументов может быть возможным здесь, как так

#include <array> 
struct NoDefault { 
    NoDefault() = delete; 
    NoDefault(int) {} 
}; 
struct Wrapper { 
    template <typename... Args> 
    Wrapper(int b_in, Args&&... args) : b{b_in}, a{args...} {} 
    int b; 
    std::array<NoDefault, 3> a; 
}; 
int main() { 
    std::array<NoDefault, 2> a {12, 34}; 
    Wrapper w {23, 12, 34, 19}; 
} 

Это, конечно, может быть дополнительно плотно стесненного добавлением enable_if s

+0

Невозможно перенаправить некоторые аргументы этому конструктору? Это единственный способ использовать вариативные шаблоны? – Curious

+0

@ Curious Я не понимаю, не могли бы вы разработать? – Brian

+0

Я хотел, чтобы конструктор класса принимал параметры, которые затем передавались в конструктор массива – Curious

2

Как я могу инициализировать массив в конструкторе для Wrapper (возможно в списке инициализаторов, используя std :: intializer_list)?

Как и любой другой член, но используйте единую инициализацию, потому что у std::array нет конструкторов.

Более конкретно, это единственный способ передать аргументы конструктору массива в списке инициализаторов для Wrapper, чтобы иметь конструкцию, аналогичную следующей:

Нет, зачем вам использовать вариативные шаблоны для фиксированного количества аргументов?

Просто ... написать конструктор с аргументами:

class Wrapper { 
    std::array<NoDefaultConstructor, 2> arr; 

    Wrapper(const NoDefaultConstructor& a, const NoDefaultConstructor& b) 
    : arr{ a, b } 
    { } 
}; 
+0

Отредактировал мой вопрос относительно того, почему я думал об использовании вариативных аргументов, теперь это имеет смысл? – Curious