Что я должен предпочесть для константы внутри функции: 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, может быть необходимо, если вы не можете позволить своей константе существовать как "переменная" во время выполнения. С перечислением, независимо от того, что вы делаете, у него не будет адреса и не будет занято место памяти (и не только из-за оптимизации компилятора, которая может возникнуть или не произойти).

В других случаях, по-видимому, нет веских оснований предпочитать друг друга.