【问题标题】:Creating a lookup table at compile time在编译时创建查找表
【发布时间】:2019-05-19 10:52:42
【问题描述】:

这里是 C++ 菜鸟。给定 constexpr f,在编译时创建数组 {f(0), f(1), ..., f(1023)} 的最简单方法是什么?

【问题讨论】:

  • 不确定您属于哪个编译器/C++ 标准,但 this 似乎可以解决问题?

标签: c++ compile-time lookup-tables


【解决方案1】:

您可以使用立即调用的 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);

【讨论】:

  • 我一直很惊讶&lt;algorithm&gt; 没有像std::generate_n 这样将索引传递给生成器的函数模板。生成器不应该携带自己的状态。
【解决方案2】:

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&lt;I...&gt;。不过如果能用c++17 DeviationN的方案就更方便了。

【讨论】:

    【解决方案3】:

    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;
    }
    

    然后,您可以使用它来创建编译时查找表:

    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);
    

    【讨论】:

      猜你喜欢
      • 2011-01-29
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-18
      相关资源
      最近更新 更多