[英]Can I define a const static instance of a class in the class header file
Is it possible to declare and define a const static instance of a class in the class header file.是否可以在 class header 文件中声明和定义 class 的 const static 实例。
I want to do something like this (from this similar question):我想做这样的事情(来自这个类似的问题):
class PlaceID {
public:
inline PlaceID(const std::string placeName):mPlaceName(placeName) {}
const static PlaceID OUTSIDE;
private:
std::string mPlaceName;
};
const PlaceID PlaceID::OUTSIDE = PlaceID("");
This would work if the definition of PlaceID::OUTSIDE was in a source file, but if it's in a header file that is include in multiple location it causes an link error because PlaceID::OUTSIDE is then defined multiple times.如果 PlaceID::OUTSIDE 的定义在源文件中,这将起作用,但如果它在包含在多个位置的 header 文件中,则会导致链接错误,因为 PlaceID::OUTSIDE 随后被定义了多次。
I'd like to define it in the header file for two reasons.我想在 header 文件中定义它有两个原因。 First, this will be part of a library and I'd like the library to be header file only.
首先,这将是库的一部分,我希望库只是 header 文件。
Second and this is the most important one I want the compiler to be allowed to "inline" the uses of this instance.其次,这是最重要的一点,我希望允许编译器“内联”该实例的使用。 The class in question (not the one used as an example here) is a wrapper around a primitive type with all methods inlined in order to offer the same performance as the primitive type would.
所讨论的 class(不是此处用作示例的那个)是原始类型的包装器,所有方法都内联以提供与原始类型相同的性能。 If I place the definition of this instance in a source file, the compiler will not know it's value at compilation time and won't be able to apply some optimisations.
如果我将此实例的定义放在源文件中,编译器将不知道它在编译时的值,也无法应用一些优化。
Thanks.谢谢。
In C++17, variables can be marked as inline
: 在C ++ 17中,变量可以标记为
inline
:
class PlaceID
{
inline const static PlaceID OUTSIDE{""};
// ...
};
Before C++14, you can use a function instead: 在C ++ 14之前,您可以改用函数:
class PlaceID
{
static PlaceID OUTSIDE() { return PlaceID{""}; }
// ...
};
...or... ...要么...
class PlaceID
{
static PlaceID OUTSIDE()
{
static PlaceID result{""};
return result;
}
// ...
};
...depending on whether or not you want a single PlaceID
instance. ...取决于您是否要使用一个
PlaceID
实例。
Alternatively, you can templatize PlaceID
over a dummy parameter in order to inline the definition of OUTSIDE
in an header: 另外,您可以在虚拟参数上模板化
PlaceID
以便在标头中内联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>;
This works because templates are implicitly inline
. 这是可行的,因为模板是隐式
inline
。 See How do inline variables work? 请参阅内联变量如何工作? for more details.
更多细节。
live example on wandbox.org wandbox.org上的实时示例
Also consider marking PlaceID::PlaceID(const char*)
as constexpr
if possible so that OUTSIDE
can be marked constexpr
as well. 如果可能的话,还可以考虑将
PlaceID::PlaceID(const char*)
标记为constexpr
,以便也可以将OUTSIDE
标记为constexpr
。 Obviously this will not work if you decide to use std::string
. 显然,如果您决定使用
std::string
则此方法将无效。
that is include in multiple location
包含在多个位置
You can stop your header from being included multiple times(and causing your problem(DISCLAIMER: I have not tested it.)) by this(which is commonly used by a lot of libraries)你可以阻止你的 header 被多次包含(并导致你的问题(免责声明:我没有测试过它。))通过这个(很多图书馆常用)
a.hpp
#ifndef LIBRARY_A
#define LIBRARY_A
//define other things
#endif
replace LIBRARY_A
for an ID of your choice(note it can't conflict with other libraries so avoid names like SOUND_SYSTEM
, but rather SOUND_LIBRARY_FOO
with FOO
replaced by your project name/your name)将
LIBRARY_A
替换为您选择的 ID(请注意,它不能与其他库冲突,因此请避免使用SOUND_SYSTEM
之FOO
的名称,而是将SOUND_LIBRARY_FOO
替换为您的项目名称/您的名称)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.