Инициализация константного массива в конструкторе с переменными параметрами - PullRequest
1 голос
/ 22 сентября 2019

Я хочу инициализировать константный массив из переменных параметров.Но с этим кодом инициализируется только первое значение в массивах значений, остальные - нули. Как это исправить?

Я никогда не имел дело с переменными параметрами и не знаю, как они в основном работают.

struct Object
{
    const int values[8];

    constexpr Object()
        : values{}
    {}

    constexpr Object(int values...)
        : values{values}
    {}
}

// in main.cpp :
Object o = { 1, 2, 3 };

Дополнительный вопрос: можно ли написать шаблон класса и сделать его размер массива равным числу переменных параметров?

Ответы [ 2 ]

2 голосов
/ 22 сентября 2019

Чтобы исправить первый код, вы можете написать:

template<class ... Values>
constexpr Object(Values ... values)
    : values{values...}
{
    static_assert(sizeof...(values) == 8);
}

По поводу вашего дополнительного вопроса:

template<int ... ints>
struct Object2
{
    const int values[sizeof...(ints)]{ints...};
};
Object2<1,21,3> o2; // array with 3 elements
std::cout << o2.values[1] << std::endl; // 21

Размер массива должен быть известен во время компиляции.Таким образом, вы не можете указать длину массива при вызове конструктора, это слишком поздно.Но вы можете использовать нетиповые параметры при создании экземпляра шаблона.

Demo

1 голос
/ 22 сентября 2019

Начиная с C ++ 17, мы можем воспользоваться пользовательскими руководствами по вычетам :

template <class T, size_t N>
class Object
{
    T d_[N];
public:
    Object() = default;

    template <class... Ts>
    constexpr Object(Ts... others) : d_{others...} {}

    constexpr auto size() const noexcept { return N; }

    constexpr auto operator[] (size_t i) const noexcept { return d_[i]; }
};

// Deduction guide
template <class T, class... Ts> Object(T, Ts...) -> Object<T, 1 + sizeof...(Ts)>;

Live, здесь .

...