static constexpr变量vs函数

use*_*436 53 c++ templates constexpr c++11

将浮点常量声明为static constexpr变量和函数(如下例所示)之间是否存在差异,还是仅仅是样式问题?

class MY_PI
{
public:
    static constexpr float MY_PI_VAR = 3.14f;
    static constexpr float MY_PI_FUN() { return 3.14f; }
}
Run Code Online (Sandbox Code Playgroud)

Mor*_*enn 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>();
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您决定使用static成员函数而不是自由函数,那么写入它不会比static成员变量更短也更容易.

constexpr 变量

使用变量的主要优点是......好吧.你想要一个常数吧?它澄清了意图,这可能是这里最重要的一点.

你仍然可以对一个类有一个等效的行为,但是如果你的类是一个包含其他数学常量的类,你必须像这样使用它:

constexpr float a = constants<float>::pi;
Run Code Online (Sandbox Code Playgroud)

或者像这样,如果你的课程只是为了代表pi:

constexpr double = pi<double>::value;
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,您可能更喜欢使用变量,因为它会更短写入,这将真正显示您正在使用常量而不是尝试计算某些东西.如果你只有一个代表pi的类,你可以使用自由constexpr函数而不是整个类.恕我直言会更简单.

C++ 14:constexpr变量模板

但请注意,如果您选择使用C++ 14而不是C++ 11,您将能够编写以下类型的constexpr变量模板:

template<typename T>
constexpr T pi = T(3.1415);
Run Code Online (Sandbox Code Playgroud)

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

constexpr float a = pi<float>;
Run Code Online (Sandbox Code Playgroud)

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

  • @ cubuspl42 [GCC支持C++ 14核心功能](http://gcc.gnu.org/projects/cxx1y.html).每个功能都有相应纸张的链接. (6认同)
  • @ cubuspl42明年应该推出的下一个C++标准.GCC和Clang已经开始实施一些功能. (4认同)
  • _(无耻插件)_我已经创建了一个概述,可以在[这里](http://theotherbranch.wordpress.com/2013/04/24/iso-c-委员会草案/)也链接到Michael Wong的出色旅行报告. (4认同)
  • @Trout.Z*"它有点太快了吗?"* - 我宁愿不要太快地调用标准但VS太慢了,不是吗? (3认同)