aki*_*kim 5 c++ constexpr c++17
我有一段将整数映射到整数的生成代码,其核心是一个简单的表。在 C++17 之前,它曾经是这样的:
int convert (int v)
{
static const int table[] = { 3, 2, 6, 1, 7, 1, 6, 8 };
if (0 <= v && v < sizeof table / sizeof table[0])
return table[v];
else
return -1;
}
Run Code Online (Sandbox Code Playgroud)
使用 C++17,我想使用 constexpr。我预计增加constexpr的函数签名就足够了,但我要删除的static表,这让我实施显然没有很好的理由更加复杂。没有太多提及,table在非constexpr情况下很可能会在堆栈上,所以我想我应该更换 static的constexpr。
G++ 8 报告:
/tmp/foo.cc: In function 'constexpr int convert(int)':
/tmp/foo.cc:14:26: error: 'table' declared 'static' in 'constexpr' function
static const int table[] = { 3, 2, 6, 1, 7, 1, 6, 8 };
^
Run Code Online (Sandbox Code Playgroud)
和 Clang++ 7:
/tmp/foo.cc:14:20: error: static variable not permitted in a constexpr function
static const int table[] = { 3, 2, 6, 1, 7, 1, 6, 8 };
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
由于我希望这段代码适用于所有 C++ 标准(并在每种情况下做正确的事情),我想我必须写这个(是的,宏,这不是问题):
#if 201703L <= __cplusplus
# define CONSTEXPR constexpr
# define STATIC_ASSERT static_assert
# define STATIC_OR_CONSTEXPR constexpr
#else
# include <cassert>
# define CONSTEXPR
# define STATIC_ASSERT assert
# define STATIC_OR_CONSTEXPR static
#endif
CONSTEXPR int convert (int v)
{
STATIC_OR_CONSTEXPR const int table[] = { 3, 2, 6, 1, 7, 1, 6, 8 };
if (0 <= v && v < sizeof table / sizeof table[0])
return table[v];
else
return -1;
}
int main()
{
STATIC_ASSERT(convert(-42) == -1);
STATIC_ASSERT(convert(2) == 6);
STATIC_ASSERT(convert(7) == 8);
STATIC_ASSERT(convert(8) == -1);
}
Run Code Online (Sandbox Code Playgroud)
所以:
是什么促使禁止在 constexpr 函数中使用静态存储变量?
有没有我可能错过的更清洁的替代品?当然,我可以table退出convert,但我想避免这种情况。
标准是否保证非 constexpr 上下文中 constexpr 函数中的 const 数组将在静态存储中而不是堆栈中?
- 有没有我可能错过的更清洁的替代方案?当然,我可以将表格从转换中取出,但我想避免这种情况。
怎么样(兼容C++11):
template <int... Ns>
struct MyTable
{
static constexpr int get(std::size_t v)
{
return v < sizeof...(Ns) ? data[v] : -1;
}
static constexpr int data[] = {Ns...};
};
constexpr int convert (std::size_t v)
{
using table = MyTable<3, 2, 6, 1, 7, 1, 6, 8>;
return table::get(v);
}
Run Code Online (Sandbox Code Playgroud)
- 标准是否保证非 constexpr 上下文中的 constexpr 函数中的 const 数组将位于静态存储而不是堆栈中?
我认为 constexpr 变量不需要具体化,将代码转换为 switch (或完美哈希)似乎是有效的实现。
所以我认为没有保证。
| 归档时间: |
|
| 查看次数: |
572 次 |
| 最近记录: |