Определите статический константный универсальный уникальный идентификатор (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. Поэтому я попробовал несколько способов присвоить значение непосредственно в заголовке, используя агрегатные инициализаторы (см. Документацию Boost для примера нестатических агрегатных инициализаторов):
static const boost::uuids::uuid classId = { 0x7f, 0xeb, ... };
К сожалению, это не удалось при компиляции (компилятор может только инициализировать статический константный интегральный тип).
Есть ли у вас какие-либо предложения по решению этой проблемы, желательно с использованием расширенной реализации UUID?
1 ответ
Самый простой способ определить нецелую константу как члена класса в заголовочном файле - это обернуть ее в функцию, например так:
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, то есть все, что нужно, уже реализовано компилятором и компоновщиком и действует с первого стандарта. И тем не менее, этой простой функции не хватает в языке. Я считаю, что это связано с некой случайной исторической эволюцией языка.
Во всяком случае, я бы пошел для простой функции оболочки, показанной в первую очередь.:-)