【问题标题】:Generate precomputed arrays using templates?使用模板生成预先计算的数组?
【发布时间】:2015-04-09 02:42:34
【问题描述】:

是否有一个好的模式可以让我使用模板从给定的元素类型、所需长度和自定义函数 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、lambda、函数指针等可能都是定义元素生成器的可接受方式。

我可能希望将模板显式实例化一次到 obj/lib 中,以便表本身只定义一次,作为可链接符号,而不是重新编译到包含标头的每个 .cpp 文件中。

【问题讨论】:

  • 类似this?有很多关于 SO 的问题类似于我所链接的问题。
  • 那里的答案非常有趣...template<std::size_t... Is> struct seq{}; 似乎应该编译为空结构,但事实并非如此。

标签: c++ templates c++11 compile-time precompute


【解决方案1】:

使用可变参数模板,您可以执行以下操作:

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

Live demo.

注意:decay_tindex_sequencemake_index_sequence 是 C++14,但可以用 C++11 编写。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-27
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多