C ++ инициализировать массив элементов с помощью аргумента конструктора - PullRequest
2 голосов
/ 29 апреля 2019

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

struct Input {
    int value;
};

template<size_t Size>
struct Foo {
    int const myVals[Size];
    Foo(std::array<Input, Size> const &in)
        : myVals{ in[0].value, in[1].value, /* How many times? */ } {
    }
}

Поскольку я не знаю размер массива, я не знаю, сколько значенийс помощью которого нужно инициализировать myVals.Следующий код работает, но я задаюсь вопросом, является ли это лучшим подходом:

template<size_t Size>
struct Foo {
    std::array<int, Size> const myVals;
    Foo(std::array<Input, Size> const &in)
        : myVals{ toIntArray(in) } {
    }
private:
    static std::array<int, Size> toIntArray(std::array<Input, Size> const &in) {
        std::array<int, Size> result;
        for (size_t i{ 0 }; i < Size; ++i) {
            result[i] = in[i].value;
        }
        return result;
    }
}

Существует ли более краткий или общепринятый способ заполнения значений массива константных членов?

1 Ответ

0 голосов
/ 10 июня 2019

Вы можете использовать std::index_sequence, чтобы получить индексы массива как нетипизированный пакет параметров шаблона.Затем вы можете использовать расширение пакета параметров.

template<size_t Size>
struct Foo {
    int const myVals[Size];
    Foo(std::array<Input, Size> const &in)
        : Foo(in, std::make_index_sequence<Size>()) { }
    private:
    template<size_t... Is>
    Foo(std::array<Input, Size> const &in, std::index_sequence<Is...>)
        : myVals{in[Is].value...} { }
}

Использование вспомогательного шаблона с пакетом size_t... Is и аргументом std::index_sequence<Is...> - это общий шаблон для обработки индексируемых контейнеров фиксированного размера.index_sequence на самом деле ничего не делает;это просто прокси, чтобы можно было вывести аргументы шаблона Is.Например, если вы проверяете Godbolt , кажется, что он полностью испаряется при -O1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...