定义静态数据成员而不重复其类型
Definition of static data member without repeating its type
当我有一个 class 和一个 static
const
或 constexpr
数据成员时,定义该变量需要我重复一些事情:
/// 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++11,C++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 没有任何链接器错误。
当我有一个 class 和一个 static
const
或 constexpr
数据成员时,定义该变量需要我重复一些事情:
/// 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++11,C++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 没有任何链接器错误。