在编译时创建查找 table
Creating a lookup table at compile time
这里是 C++ 菜鸟。给定一个 constexpr f
,在编译时创建数组 {f(0), f(1), ..., f(1023)}
的最简单方法是什么?
您可以使用立即调用的 lambda:
#include <array>
using ResultT = int;
constexpr ResultT f(int i)
{
return i * 2;
}
constexpr auto LUT = []
{
constexpr auto LUT_Size = 1024;
std::array<ResultT, LUT_Size> arr = {};
for (int i = 0; i < LUT_Size; ++i)
{
arr[i] = f(i);
}
return arr;
}();
static_assert(LUT[100] == 200);
DeviationN 的解决方案需要 C++17(对于 constexpr lambda)。
作为补充,这里有一个使用 C++14 的解决方案
#include <array>
constexpr int f(int i) { return 2 * i; }
template <std::size_t... I>
constexpr auto lookup_helper(std::index_sequence<I...>)
{
return std::array<int, sizeof...(I)>({f(I)...});
}
template <size_t N>
constexpr auto lookup()
{
return lookup_helper(std::make_index_sequence<N>());
}
int main()
{
constexpr int N = 10;
constexpr auto a = lookup<N>();
// Check it works
static_assert(a[N-1]==2*(N-1));
}
想法是使用std::index_sequence<I...>
。不过如果能用c++17 DeviationN的解决方案就更方便了。
lambda 解决方案适合一次性使用。如果你必须做几个,你可以用这样的constexpr函数模板概括它:
#include <algorithm>
#include <array>
#include <cstdint>
template <typename T, std::size_t N, typename Generator>
constexpr std::array<T, N> make_array(Generator fn) {
std::array<T, N> table = {};
for (std::size_t i = 0; i != N; ++i) {
table[i] = fn(i);
}
return table;
}
然后,您可以使用它来创建编译时查找 table:
constexpr float doubler(std::size_t i) { return 2.0f * i; }
constexpr auto lookup_table = make_array<float, 5>(doubler);
static_assert(lookup_table[3] == 6.0f);
这里是 C++ 菜鸟。给定一个 constexpr f
,在编译时创建数组 {f(0), f(1), ..., f(1023)}
的最简单方法是什么?
您可以使用立即调用的 lambda:
#include <array>
using ResultT = int;
constexpr ResultT f(int i)
{
return i * 2;
}
constexpr auto LUT = []
{
constexpr auto LUT_Size = 1024;
std::array<ResultT, LUT_Size> arr = {};
for (int i = 0; i < LUT_Size; ++i)
{
arr[i] = f(i);
}
return arr;
}();
static_assert(LUT[100] == 200);
DeviationN 的解决方案需要 C++17(对于 constexpr lambda)。
作为补充,这里有一个使用 C++14 的解决方案
#include <array>
constexpr int f(int i) { return 2 * i; }
template <std::size_t... I>
constexpr auto lookup_helper(std::index_sequence<I...>)
{
return std::array<int, sizeof...(I)>({f(I)...});
}
template <size_t N>
constexpr auto lookup()
{
return lookup_helper(std::make_index_sequence<N>());
}
int main()
{
constexpr int N = 10;
constexpr auto a = lookup<N>();
// Check it works
static_assert(a[N-1]==2*(N-1));
}
想法是使用std::index_sequence<I...>
。不过如果能用c++17 DeviationN的解决方案就更方便了。
lambda 解决方案适合一次性使用。如果你必须做几个,你可以用这样的constexpr函数模板概括它:
#include <algorithm>
#include <array>
#include <cstdint>
template <typename T, std::size_t N, typename Generator>
constexpr std::array<T, N> make_array(Generator fn) {
std::array<T, N> table = {};
for (std::size_t i = 0; i != N; ++i) {
table[i] = fn(i);
}
return table;
}
然后,您可以使用它来创建编译时查找 table:
constexpr float doubler(std::size_t i) { return 2.0f * i; }
constexpr auto lookup_table = make_array<float, 5>(doubler);
static_assert(lookup_table[3] == 6.0f);