У меня есть этот кусок сгенерированного кода, который отображает целые числа в целые, ядро которых представляет собой простую таблицу.В до 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
таблицы, что делает мою реализацию более сложной, по-видимому, без веской причины.Не стоит также упоминать, что table
в контексте non 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 };
^
и 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?
есть ли более чистая альтернатива, которую я мог пропустить?Конечно, я могу извлечь table
из convert
, но я бы хотел этого избежать.
обеспечивает стандартную гарантию того, что константные массивы в функциях constexpr в контекстах не-constexpr будутбыть в статическом хранилище вместо стека?