定义静态数据成员而不重复其类型

Definition of static data member without repeating its type

当我有一个 class 和一个 static constconstexpr 数据成员时,定义该变量需要我重复一些事情:

/// my_class.hpp
class my_class { constexpr static int x = 1; };
/// my_class.cpp
#include "my_class.hpp"
// auto my_class::x; // error: declaration of 'auto my_class::x' has no initializer
// decltype(auto) my_class::x; // error: declaration of 'decltype(auto) my_class::x' has no initializer
decltype(my_class::x) my_class::x; // ok

当然可以

#define DEFINE_STATIC_DATA_MEMBER(x) decltype(x) x
DEFINE_STATIC_DATA_MEMBER(my_class::x);

但是不知道有没有非宏的解决方法

出现这个问题是因为静态数据成员的类型和完全限定名称都很长,我可能会得到更多。

您可以使用 typedef 来避免在定义类型时重复类型。

my_class.hpp

class my_class
{
    // Declaration
    static const my_very_lengthy_type_name_I_dont_want_to_repeat x;

    // typedef
    using t = decltype(x);
};

my_class.cpp

#include "my_class.hpp"

// Initialization
my_class::t my_class::x = {};

从 C++17 开始,您不需要单独定义 static constexpr 个变量。

只需 class my_class { constexpr static int x = 1; }; 即可,无需 .cpp 文件。

defining that variable requires me to repeat stuff:

对于static constexpr数据成员,上述说法只对Pre-C++17标准成立。

从 C++17 开始,我们可以省略编写 out-of-class 数据成员的 static constexpr 定义。这在下面给出的示例中有所说明。

C++11

class Foo
{
public:
    static constexpr int OUT_OF_BOUNDS_VALUE = -9999; //THIS IS A DECLARATION IN C++11 and C++14
    //other members here
};

在上面的代码片段中(针对C++11C++14),我们有一个[= class 内部的静态数据成员 OUT_OF_BOUNDS_VALUE 的 44=] 声明。因此,在 exactly one translation unit 中,我们必须提供相应的 definition。否则你会得到一个 链接器错误 可以看到 here.

也就是说,在正好一个翻译单元中我们应该写:

constexpr int Foo::OUT_OF_BOUNDS_VALUE;  //note no initializer

将上述 class 定义添加到 no initializer the program will work. Demo

之后

C++17

但是从 C++17 开始不再需要 static constexpr 的 out-of-class 定义。

class Foo
{
public:
    static constexpr int OUT_OF_BOUNDS_VALUE = -9999; //THIS IS A DEFINITION IN C++17
    //other members here
};

在上面的代码片段中(针对 C++17)我们有一个 定义 静态数据成员 OUT_OF_BOUNDS_VALUE 在 class 里面。因此,从 C++17 开始,我们不必在其他任何地方提供 OUT_OF_BOUNDS_VALUE 定义,因为我们已经在 class 和因此相同的程序 works 没有任何链接器错误。