定义静态const通用唯一标识符(UUID)

时间:2012-10-18 08:51:38

标签: c++ uuid boost-uuid

上下文

我经常使用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。因此,我尝试了几种使用聚合初始化器直接在头中分配值的方法(有关非静态聚合初始化器的示例,请参阅boost documentation):

  static const boost::uuids::uuid classId = { 0x7f, 0xeb, ... };

不幸的是,它在编译时失败了(编译器只能初始化静态const积分类型)。

您是否有任何建议可以解决此问题,最好使用UUID的Boost实现?

1 个答案:

答案 0 :(得分:2)

在头文件中将非整数常量定义为类成员的最简单方法是将其包装在函数中,如下所示:

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没有链接器警告的测试编译很好,但它是如此新,以至于我不确定标准的One Definition Rule是否实际支持它,或者是否在多个翻译中使用这样的定义单位,我是未定义的行为。

所以,如果你想做constexpr,可能会问一个关于ODR的单独问题。

作为替代方案,您可以等待C ++ 2040标准,然后再编写

inline static Uuid const uuid = ...;

如图所示,即使在C ++ 98中,这个假设的未来特征也可以仿真,这是值得深思的,即所有需要的东西已经由编译器和链接器实现,并且已经被自第一个标准。然而,这种简单的功能缺乏语言。我认为这是由于一种随意的历史语言演变。

无论如何,我会先找一下简单的函数包装器。 : - )