Класс с массивом объектов std:: без конструкторов по умолчанию
Итак, давайте предположим, что у меня есть следующий класс
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)...} {}
2 ответа
std::array
должен быть совокупным. Поэтому он не имеет нетривиальных конструкторов, но может быть инициализирован с использованием агрегатной инициализации. Обратите внимание, что агрегатная инициализация включает в себя список инициализированных скобок (то есть, список инициализаторов, заключенный в фигурные скобки), но не std::initializer_list
объект.
class Wrapper {
public:
Wrapper() : arr {MakeNoDefaultConstructor(123),
MakeNoDefaultConstructor(456)} {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ braced-init-list
private:
std::array<NoDefaultConstructor, 2> arr;
};
РЕДАКТИРОВАТЬ Конструктор с переменными аргументами может быть возможно здесь, так
#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
Как я могу инициализировать массив в конструкторе для Wrapper (возможно, в списке инициализаторов, используя std::intializer_list)?
Как и для любого другого члена, но используйте единую инициализацию, потому что std::array
не имеет конструкторов.
Точнее говоря, единственный ли способ передать аргументы конструктору массива в списке инициализатора, чтобы Wrapper имел конструкцию, подобную следующей?
Нет, зачем вам использовать шаблоны с переменным числом аргументов для фиксированного числа аргументов?
Просто... напишите конструктор с аргументами:
class Wrapper {
std::array<NoDefaultConstructor, 2> arr;
Wrapper(const NoDefaultConstructor& a, const NoDefaultConstructor& b)
: arr{ a, b }
{ }
};