假设为了参数我在类中有以下私有constexpr:
static constexpr uint16_t square_it(uint16_t x)
{
return std::pow(x, 2);
}
然后我想使用上面的constexpr在同一个类的同一部分中为最多255个整数构造这些值的静态常量数组:
static const uint16_t array_of_squares[256] =
{
//something
};
我希望在编译时构造数组,如果可能的话,不要在运行时构建。我认为第一个问题是在constexpr中使用像std :: pow这样的表达式是无效的ISO C ++(尽管arm-gcc可能允许?),因为它可以返回域错误。我想要使用的实际表达式是一个涉及std :: exp。
的有点复杂的函数请注意,由于我正在为一个小型微处理器Cortex M4进行编译,因此我没有太多可用的std库。
有没有更合适的方法来执行此操作,比如使用预处理器宏?我非常希望避免使用像外部Python脚本这样的东西来计算每次在开发过程中需要修改表格,然后粘贴它。
答案 0 :(得分:1)
正如您所说,问题是C标准库函数通常没有标记为constexpr
。
如果您需要使用std::exp
,这里最好的解决方法是编写您自己的可以在编译时运行的实现。如果它是在编译时完成的,那么可能没有必要对其进行优化,它只需要准确且适度有效。
很久以前有人问过如何做here的问题。您可以从那里重用该想法并在C ++ 11中重写为constexpr
函数,尽管您必须重构它以避免for循环。在C ++ 14中,需要更少的重构。
您也可以尝试通过模板严格执行此操作,但这会更加痛苦,double
不能成为模板参数,因此会更复杂。
答案 1 :(得分:1)
这样的事情怎么样?
constexpr uint16_t square_it(uint16_t v) { return v*v; }
template <size_t N, class = std::make_index_sequence<N>>
struct gen_table;
template <size_t N, size_t... Is>
struct gen_table<N, std::index_sequence<Is...>> {
static const uint16_t values[N] = {square_it(Is)...};
};
constexpr auto&& array_of_squares = gen_table<256>::values;
我不知道微处理器是否支持这种操作。它可能在您的标准库中没有make_index_sequence
(尽管您可以在SO上找到实现),也许该模板实例化会占用太多内存。但至少它可以在某个地方运作。