上下文
我经常使用 Boost 库的 UUID 实现来识别派生类。
为此,我通常使用以下内容:
在声明文件中:
#include "ClassA.h"
#include <boost/uuid/uuid.hpp>
class SubClass1 : public ClassA {
public:
static const boost::uuids::uuid classId; // 7feb24af-fc38-44de-bc38-04defc3804de
...
};
在实现文件中:
#include "SubClass1.h"
#include <boost/uuids/uuid_generator.h>
const boost::uuids::uuid SubClass1 ::classId = boost::uuids::string_generator()("{7feb24af-fc38-44de-bc38-04defc3804de}");
...
问题
我想知道是否可以在声明文件中为 UUID 赋值。
想法
一开始我认为这是可能的,因为Boost的实现是POD。因此,我尝试了多种方法使用聚合初始值设定项直接在 header 中分配值(有关非静态聚合初始值设定项的示例,请参阅 boost documentation):
static const boost::uuids::uuid classId = { 0x7f, 0xeb, ... };
不幸的是,它编译失败(编译器只能初始化静态const整型)。
您对解决此问题有什么建议吗?最好使用 UUID 的 Boost 实现?
最佳答案
在头文件中将非整数常量定义为类成员的最简单方法是将其包装在函数中,如下所示:
typedef whatever Uuid;
class MyClass
{
public:
static Uuid const& uuid()
{
Uuid const theValue = ...;
return theValue;
}
};
如果您希望它作为实际常量而不是函数,那么您可以使用一些模板技巧,如下所示:
template< class Dummy >
class MyClass_constants
{
public:
static Uuid const uuid;
};
template< class Dummy >
Uuid const MyClass_constants<Dummy>::uuid = ...;
class MyClass
: public MyClass_constants<void>
{};
在 C++11 中,您可以使用 constexpr
,如下所示:
class MyClass
{
public:
static Uuid constexpr uuid = ...;
};
但是,虽然 g++ 4.7.1 的测试编译得很好,没有链接器警告,但它太新了,我不确定标准的单一定义规则是否真正支持它,或者是否在多重翻译中使用这样的定义单位,我很喜欢未定义的行为。
因此,如果您想要执行 constexpr
,也许可以询问有关 ODR 的单独问题。
作为替代方案,您可以等待 C++2040 标准,然后编写
inline static Uuid const uuid = ...;
值得深思的是,如图所示,即使在 C++98 中也可以模拟这个假设的 future 功能,即所需的一切都已由编译器和链接器实现,并且已被自第一个标准以来。然而,该语言缺乏这个简单的功能。我相信这是由于一种偶然的历史语言演变造成的。
无论如何,我会选择首先显示的简单函数包装器。 :-)
关于c++ - 定义静态常量通用唯一标识符(UUID),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12950677/