Определите статический константный универсальный уникальный идентификатор (UUID)

контекст

Я часто использую UUID-реализацию библиотеки Boost для идентификации производных классов.
Для этого я обычно использую следующее:
В файле декларации:

  #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. Поэтому я попробовал несколько способов присвоить значение непосредственно в заголовке, используя агрегатные инициализаторы (см. форсировать документацию для примера нестатических агрегатных инициализаторов):

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

К сожалению, это не удалось при компиляции (компилятор может только инициализировать статический константный интегральный тип).

Есть ли у вас какие-либо предложения по решению этой проблемы, желательно с использованием расширенной реализации UUID?

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Возможно, задайте отдельный вопрос об УСО.

В качестве альтернативы вы можете подождать до стандарта C ++ 2040, а затем просто написать

inline static Uuid const uuid = ...;

Это пища для размышлений, что, как показано, эта гипотетическая будущая особенность может быть эмулировать даже в C ++ 98, т. е. все, что нужно, уже реализовано компилятором и компоновщиком, и было с первого стандарта. И тем не менее, этой простой функции не хватает в языке. Я считаю, что это связано с некой случайной исторической эволюцией языка.

Во всяком случае, я бы пошел для простой функции оболочки, показанной в первую очередь. 🙂

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]