Подтвердить что ты не робот

Статическая константа constexpr vs function

Есть ли разница между объявлением константы с плавающей запятой как переменной static constexpr и функцией, как в примере ниже, или это просто вопрос стиля?

class MY_PI
{
public:
    static constexpr float MY_PI_VAR = 3.14f;
    static constexpr float MY_PI_FUN() { return 3.14f; }
}
4b9b3361

Ответ 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 это может быть предпочтительный способ сделать что-то. Если вы используете более старую версию стандарта, первые два абзаца все еще сохраняются.