static constexpr变量vs函数

时间:2013-04-29 20:36:43

标签: c++ templates c++11 constexpr

将浮点常量声明为static constexpr变量与下面的示例中的函数之间是否有区别,或者只是样式问题?

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

1 个答案:

答案 0 :(得分:54)

constexpr函数

函数有一个优点,即自由变量没有(直到C ++ 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函数而不是整个类。恕我直言会更简单。

C ++ 14:constexpr variable templates

但请注意,如果您选择使用C ++ 14而不是C ++ 11,则可以编写以下constexpr变量模板:

template<typename T>
constexpr T pi = T(3.1415);

这将允许您编写如下代码:

constexpr float a = pi<float>;

从C ++ 14开始,这可能是首选的方法。如果您使用的是旧版本的标准,前两段仍然有效。