Как заставить производный тип массива принимать агрегатную инициализацию?

Например

class A : public std::array<int, 3>
{
};

А также

A a{1, 2, 3}; // failed currently.

Как заставить производный тип массива принимать агрегатную инициализацию?

3 ответа

Решение

Вы могли бы предоставить конструктор шаблонов с переменными параметрами следующим образом:

class A : public std::array<int, 3> {
public:
  template<typename... Args> constexpr A(Args&& ...args) 
    : std::array<int, 3>{{std::forward<Args>(args)...}} {}
};

Live Demo

Редактировать:

Следующая версия работает также на Visual Studio:

class A : public std::array<int, 3> {
public:
    template<typename... Args> constexpr A(Args&& ...args) 
      : std::array<int, 3>(std::array<int,3>{std::forward<Args>(args)...}) {}
};

Live Demo

РЕДАКТИРОВАТЬ: Как другие отмечали в комментариях, это не будет работать для std::array так как std::array не содержит конструктор initializer_list, Но это может быть полезно для других контейнеров, которые принимают конструктор initializer_list, например std::vector,

Вы можете использовать наследующий конструктор(начиная с C++11):

class A: public std::vector<int,3>
{
      using std::vector<int,3>::vector;
};

Просто определите конструктор так:

A(std::array<int, 3>);

пример:

#include <array>
#include <iostream>

struct A : public std::array<int, 3>
{
    A(std::array<int, 3>    a) :
        std::array<int, 3>{a}
    {
    }
};

int main(void)
{
    A   a({1, 2, 3});

    std::cout << a[0] << "\n";
    std::cout << a[1] << "\n";
    std::cout << a[2] << "\n";
}

Это не совокупная инициализация, а "как будто"...

Другие вопросы по тегам