Что я должен предпочесть для константы внутри функции: constexpr const или enum?
Я использую для определения своих констант с enum { my_const = 123; }
, поскольку в классах использование static constexpr
требует некоторого кода вне определения класса (см. этот вопрос). Но как насчет в функциональных органах? В последнее время я замечал людей, у которых были только переменные constexpr
в своих функциях (даже не беспокоило их на const
), и мне было интересно, я ли я дурак, кто позади с моим
int foo(int x)
{
enum : int { bar = 456 };
return x + bar;
}
Итак, мой вопрос: есть ли какая-либо польза для использования перечисления в телах функций, а не в переменных constexpr?
Ответы
Ответ 1
Вы можете случайно или по назначению установить ODR-существование bar
, если это было constexpr int bar = 456;
, это невозможно с помощью enum : int { bar = 456 };
.
Это может быть или не быть преимуществом с обеих сторон.
Например
int baz(int const* ptr ) {
if (ptr) return 7; return -1;
}
int foo(int x)
{
// enum : int { bar = 456 };
constexpr int bar = 456;
return x + baz(&bar);
}
версия enum
не компилируется, это делает constexpr int
. A constexpr int
может быть lvalue, перечислитель (одна из перечисленных констант перечисления) не может.
Значения перечисления на самом деле не являются int
, а constexpr int
- фактически int
. Это может иметь значение, если вы передадите его на
template<class T>
void test(T) {
static_assert(std::is_same<T,int>::value);
}
один пройдет тест; другой не будет.
Опять же, это может быть преимуществом, недостатком или бессмысленной причудой в зависимости от того, как вы используете токен.
Ответ 2
Один вкладыш на основе @Yakk (но это мой собственный):
с использованием констант, основанных на enum
, может быть необходимо, если вы не можете позволить своей константе существовать как "переменная" во время выполнения. С перечислением, независимо от того, что вы делаете, у него не будет адреса и не будет занято место памяти (и не только из-за оптимизации компилятора, которая может возникнуть или не произойти).
В других случаях, по-видимому, нет веских оснований предпочитать друг друга.