Рассмотрим следующий код:
struct A
{
// No data members
//...
};
template<typename T, size_t N>
struct B : A
{
T data[N];
}
Вот как вы должны инициализировать B: B<int, 3> b = { {}, {1, 2, 3} };
я хочу избежать ненужного пустого {} для базового класса. Существует решение , предложенное Jarod42 здесь , однако, он не работает с элементами по умолчанию инициализации: B<int, 3> b = {1, 2, 3};
это хорошо , но B<int, 3> b = {1};
это не так : b.data[1]
и b.data[2]
не дефолт инициализируется в 0, и возникает ошибка компиляции. Есть ли способ (или будет с c ++ 20) «скрыть» базовый класс от конструкции?
c++
initialization
c++20
aggregate-initialization
user7769147
источник
источник
template<class... Ts> B(Ts... args) : data{args...} {}
?Ответы:
Самое простое решение - добавить конструктор переменных:
Если вы предоставите меньше элементов в
{...}
списке инициализатора, чемN
, остальные элементы в массивеdata
будут инициализированы значением какT()
.источник
B<Class, 5> b = {Class()};
Class
, что сначалаClass
будетstd::tuple
аргументы и использовать их для создания объектов на месте. Но синтаксис будет довольно громоздким.Начиная с C ++ 20 вы можете использовать обозначенные инициализаторы в агрегатной инициализации .
источник
Еще с конструктором, вы можете сделать что-то вроде:
демонстрация
SFINAE делается главным образом, чтобы избежать создания псевдокопировального конструктора.
B(B&)
.Вам понадобится дополнительный приватный тег для поддержки
B<std::index_sequence<0, 1>, 42>
;-)источник
((void)Is, T())...
? Что если вы просто пропустите это? Не будут ли остальные элементы инициализированыT()
по умолчанию?Я нашел другое решение, которое (я не знаю, как) прекрасно работает и решает проблему, которую мы обсуждали под ответом Evg.
источник
this->data
илиusing B_data::data;
получить доступdata
внутрьB
.