Как статически инициализировать один массив, используя другой массив constexpr - PullRequest
2 голосов
/ 27 марта 2019

У меня есть массив constexpr, подобный этому:

constexpr std::array<int, 4> BASES_TO_CHECK = { 8, 16, 32, 64 };

Я хотел бы сделать что-то похожее на:

std::array<std::thread, BASES_TO_CHECK.size()> calc;
for(size_t i = 0; i<BASES_TO_CHECK.size(); ++i)
{
    calc[i]=std::thread(calculate<BASES_TO_CHECK[i]>,  std::ref(recordMap[BASES_TO_CHECK[i]]),  std::ref(counterMap.at(BASES_TO_CHECK[i])),  std::ref(done));
}

Однако, поскольку переменная используется в качестве шаблонапараметр, так что это не сработает.Я закончил тем, что сделал это:

std::array<std::thread, BASES_TO_CHECK.size()> calc = {
    std::thread(calculate<BASES_TO_CHECK[0]>,  std::ref(recordMap[BASES_TO_CHECK[0]]),  std::ref(counterMap.at(BASES_TO_CHECK[0])),  std::ref(done)),
    std::thread(calculate<BASES_TO_CHECK[1]>,  std::ref(recordMap[BASES_TO_CHECK[1]]),  std::ref(counterMap.at(BASES_TO_CHECK[1])),  std::ref(done)),
    std::thread(calculate<BASES_TO_CHECK[2]>,  std::ref(recordMap[BASES_TO_CHECK[2]]),  std::ref(counterMap.at(BASES_TO_CHECK[2])),  std::ref(done)),
    std::thread(calculate<BASES_TO_CHECK[3]>,  std::ref(recordMap[BASES_TO_CHECK[3]]),  std::ref(counterMap.at(BASES_TO_CHECK[3])),  std::ref(done))
};

И это работает, но я полагаюсь на то, что я не изменяю количество элементов в BASES_TO_CHECK без ручного обновления части кода, где массив calcинициализируется.

1 Ответ

3 голосов
/ 27 марта 2019
template<std::size_t... i>
std::array<std::thread, BASES_TO_CHECK.size()> gen_impl(std::index_sequence<i...>) {
    return {
                std::thread(calculate<BASES_TO_CHECK[i]>,
                            std::ref(recordMap[BASES_TO_CHECK[i]]),
                            std::ref(counterMap.at(BASES_TO_CHECK[i])),
                            std::ref(done)
                           )...
           };
}

auto calc = gen_impl(std::make_index_sequence<BASES_TO_CHECK.size()>{});
...