使用 boost::hana 创建一个大的编译时间映射

Creating a big compile time map using boost::hana

我正在尝试使用 boost::hana 创建一个 constexpr 查找 table,它变得相当大(最多 32768 个元素)。这是我的代码:

#include <boost/hana.hpp>
#include <boost/hana/assert.hpp>

namespace hana = boost::hana;

template <typename Count>
static constexpr auto createLookupTable(void)
{
    auto indices = hana::make_range(hana::int_c<0>, hana::int_c<Count::value>);

    return hana::unpack(indices, [](auto... index)
    {
        return hana::make_map(
            hana::make_pair(
                index,
                hana::int_c<0>)...);
    });
}

int main()
{
    constexpr auto lookupTable = createLookupTable<std::integral_constant<unsigned, 128>>();
    BOOST_HANA_CONSTANT_CHECK(hana::length(lookupTable) == hana::size_c<128>);
}

出于测试目的,每对的值为 hana::int_c<0>。这被一些有意义的东西所取代。 编译这个需要一些时间。使用 hana 有没有更快的方法?

谢谢

It tooks some time to compile this. Is there a faster way to do it?

我不认为它是 hana (which I don't know and that I am discovering). Compilation of templated C++ code is complex and slow, and takes some time (since C++ template expansion is Turing complete 特有的,它可能需要任意长的时间)。

模板代码的编译在 2018 年 5 月 GCC and of Clang, so use a recent version (e.g. GCC 8 的最新版本中得到了显着改进)如果可以的话。

在实践中(如果你负担得起的话),我建议在编译时初始化一个大的 POD structs 数组,或者在你的情况下初始化一个整数数组,也许通过生成 C++(或甚至 C) 将其归档,并在初始化时(因此在 运行 时间)将该数组转换为您的 hana

否则,将您的 hana 模板初始化留在一些单独的文件中,并接受编译需要很多时间(但在 运行 时它会 运行 非常快).也许 ccache 可能有用。

当您处理稀疏索引或键没有顺序时,映射是表示查找的正确工具table。

由于您处理的是连续整数作为查找 table 键,因此您确实应该坚持使用旧的 C 风格数组,或者更好的是,std::array<128, your_value_type>:

constexpr std::array<128, your_value_type> lookupTable = {
    // ...
};

完成后,您可以将 table 的构造委托给 constexpr 模板函数:

template<unsigned size>
constexpr std::array<size, your_value_type> lookupTable()
{
    return /* ... */;
}
constexpr auto lookupTable = lookupTable<128>();