Замена констант: когда использовать статический constexpr и встроенный constexpr? - PullRequest
0 голосов
/ 31 января 2019

Этот вопрос является дополнительным вопросом к C ++ 17: все еще используются перечисления в качестве констант? .

Устаревшие константы бывают нескольких форм, в частности:

  • #define CONSTANT x
  • enum { CONSTANT = x };
  • const /*int/unsigned/whatever*/ CONSTANT = x;

Комментарий о static constexpr и inline constexpr константах в качестве замены заставил меня задуматься опредмет обновления наших многих, многих унаследованных констант (в частности, #define констант).

Как я понимаю, значение inline constexpr в основном просто подставляется на месте, как встроенная функция (которой я былпоказано, что неправильно).И наоборот, значение static constexpr сохраняется как часть двоичного файла в отдельной области.Предполагая, что я правильно понимаю, когда один должен быть предпочтительнее другого?Я догадываюсь, что для интегральных констант обычно предпочтительнее будет inline constexpr.

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Ваш переход к глобальным константам в C ++ 17 должен быть следующим:

inline constexpr int CONSTANT = 42;

Это дает вам хорошую первоклассную переменную, которую вы можете использовать в константных выражениях, и которая не будетесть ODR-проблемы.Вы можете взять ссылки на него.

Макросы вызывают проблему ... быть макросами.Перечисления ограничены целочисленными типами.С constexpr переменными вы можете иметь их любого литерального типа.В C ++ 20 вы, скорее всего, сможете просто сойти с ума и написать:

inline constexpr std::vector<int> small_primes = {2, 3, 5, 7, 11};
inline constexpr std::string cool_name = "Barry";

Это единственный вариант, который позволяет это.

0 голосов
/ 31 января 2019

В C ++ 17, правильный способ заменить эти старые идиомы (например, #define) в заголовках в области пространства имен - это использовать constexpr inline переменных - и не static (чтоподразумевается: они уже имеют внутреннюю связь).

Хотя обычно у вас не возникает проблем с ODR (потому что целочисленные константы времени компиляции, такие как те, которые вы описываете, редко используются ODR, и есть положение для их типичныхиспользование в inline функциях), лучше всего пометить их как inline, теперь, когда у нас есть особенность в языке и мы избегаем всех проблем.

См. Должны ли `const` и` constexpr`переменные в заголовках должны быть `inline` для предотвращения нарушений ODR? для технических деталей об этом.

...