Ответ 1
constexpr
функции
Функции имеют преимущество в том, что свободные переменные не имеют (до С++ 14): их можно легко планировать без какого-либо шаблона класса. Это означает, что вы можете иметь pi
с точностью в зависимости от аргумента шаблона:
template<typename T>
constexpr T pi();
template<>
constexpr float pi() { return 3.14f; }
template<>
constexpr double pi() { return 3.1415; }
int main()
{
constexpr float a = pi<float>();
constexpr double b = pi<double>();
}
Однако, если вы решите использовать функцию-член static
вместо свободной функции, она не будет короче или легче писать, чем переменная-член static
.
constexpr
переменные
Основным преимуществом использования переменной является то, что... хорошо. Вы хотите постоянного, не так ли? Он уточняет намерение и может быть одним из самых важных моментов здесь.
Вы все равно можете иметь эквивалентное поведение с классом, но тогда вам придется использовать его так, если ваш класс является классом, содержащим разные математические константы:
constexpr float a = constants<float>::pi;
Или, например, если ваш класс предназначен только для представления pi
:
constexpr double = pi<double>::value;
В первом случае вы можете использовать переменные, поскольку они будут короче писать, и это действительно покажет, что вы используете константу и не пытаетесь что-то вычислить. Если у вас есть класс, представляющий pi, вы можете, однако, перейти со свободной функцией constexpr
вместо целого класса. Это было бы ИМХО проще.
С++ 14: constexpr
шаблоны переменных
Однако обратите внимание, что если вы решите использовать С++ 14 вместо С++ 11, вы сможете написать следующие типы шаблонов constexpr
:
template<typename T>
constexpr T pi = T(3.1415);
Это позволит вам написать свой код следующим образом:
constexpr float a = pi<float>;
В С++ 14 это может быть предпочтительный способ сделать что-то. Если вы используете более старую версию стандарта, первые два абзаца все еще сохраняются.