是否可以在类头文件中声明和定义一个类的const static实例。
我想做这样的事情(来自 this 类似的问题):
class PlaceID {
public:
inline PlaceID(const std::string placeName):mPlaceName(placeName) {}
const static PlaceID OUTSIDE;
private:
std::string mPlaceName;
};
const PlaceID PlaceID::OUTSIDE = PlaceID("");
如果 PlaceID::OUTSIDE 的定义在源文件中,这将起作用,但如果它在包含在多个位置的头文件中,则会导致链接错误,因为 PlaceID::OUTSIDE 随后被定义了多次。
我想在头文件中定义它有两个原因。首先,这将是库的一部分,我希望该库只是头文件。
其次,这是最重要的一点,我希望允许编译器“内联”该实例的使用。所讨论的类(不是此处用作示例的类)是原始类型的包装器,所有方法都内联以提供与原始类型相同的性能。如果我将此实例的定义放在源文件中,编译器将不知道它在编译时的值,也无法应用一些优化。
谢谢。
最佳答案
在C++17中,变量可以被标记为inline
:
class PlaceID
{
inline const static PlaceID OUTSIDE{""};
// ...
};
在 C++14 之前,您可以改用函数:
class PlaceID
{
static PlaceID OUTSIDE() { return PlaceID{""}; }
// ...
};
……或者……
class PlaceID
{
static PlaceID OUTSIDE()
{
static PlaceID result{""};
return result;
}
// ...
};
...取决于您是否需要单个 PlaceID
实例。
或者,您可以在虚拟参数上对 PlaceID
进行模板化,以便在 header 中内联 OUTSIDE
的定义:
template <typename>
struct PlaceID_
{
inline PlaceID_(const char*) { }
const static PlaceID_ OUTSIDE;
};
template <typename T>
const PlaceID_<T> PlaceID_<T>::OUTSIDE{""};
using PlaceID = PlaceID_<void>;
之所以可行,是因为模板是隐式内联
。参见 How do inline variables work?了解更多详情。
还可以考虑将 PlaceID::PlaceID(const char*)
标记为 constexpr
如果可能,这样 OUTSIDE
可以标记为 constexpr
也是。显然,如果您决定使用 std::string
,这将不起作用。
关于c++ - 我可以在类头文件中定义类的 const static 实例吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47265300/