Генерировать предварительно вычисленные массивы, используя шаблоны?

Есть хороший шаблон, который позволит мне использовать шаблоны для генерации предварительно вычисленного массива из заданного типа элемента, желаемой длины и пользовательской функции f(int index)?

Рассмотрим эту реализацию в стиле C

#define FORLIST_1(fOfi)   (fOfi)(0)
#define FORLIST_2(fOfi)   FORLIST_1(fOfi) , (fOfi)(1 )
#define FORLIST_3(fOfi)   FORLIST_2(fOfi) , (fOfi)(2 )
#define FORLIST_4(fOfi)   FORLIST_3(fOfi) , (fOfi)(3 )
//... And so on

// Toy example user-specified function which describes how to create the table
double genEntry(u32 i) {
return i == 0 ? 0 : std::log(i) / std::log(5);
}

// Generate a precomputed lookup table
// FORLIST_15 expands into genEntry(0), genEntry(1), genEntry(2), ...
const double lookupTable[16] = {
FORLIST_16(genEntry)
};

Какой самый чистый способ сделать то же самое с шаблонами? Он должен позволять мне указывать количество элементов в массиве и предоставлять какую-то пользовательскую функцию (индекс в качестве параметра). функторы, std::functionлямбда, указатель на функцию и т. д., вероятно, все приемлемые способы определения генератора элементов.

Я, вероятно, захочу один раз явным образом создать экземпляр шаблона в obj / lib, чтобы сама таблица определялась только один раз как связываемый символ, а не перекомпилировалась в каждый файл .cpp, содержащий заголовок.

1

Решение

С помощью шаблона variadic вы можете сделать что-то вроде:

template <typename F, std::size_t ... Is>
auto
make_array(F f, std::index_sequence<Is...>)
-> std::array<std::decay_t<decltype(f(0u))>, sizeof...(Is)>
{
return {{f(Is)...}};
}

Живая демо.

Замечания: decay_t, index_sequence а также make_index_sequence являются C ++ 14, но могут быть написаны на C ++ 11.

1

Другие решения


По вопросам рекламы [email protected]