我有一段生成的代码,用于将整数映射到整数,其核心是一个简单的表格。在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;
}
使用C++17,我想使用constexpr。 我原以为只需将
constexpr
添加到函数签名中就足够了,但我必须移除表格的static
,这使得我的实现更加复杂,而且没有明显的好处。更不用说在非constexpr上下文中,table
可能会在堆栈上,所以我想应该用constexpr
来替换static
。
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 };
^
以及 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.
我希望这段代码能够适用于所有的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);
}
所以:
为什么constexpr函数中禁止使用静态存储变量?这是什么动机引起的?
有没有更简单的替代方案?当然,我可以将从中提取出来,但我想避免这样做。
标准是否保证constexpr函数中的const数组在非constexpr上下文中将位于静态存储而不是堆栈中?