Я часто использую 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?
Самый простой способ определить нецелую константу как ученик в заголовочном файле это обернуть его в функцию, например так:
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, т. е. все, что нужно, уже реализовано компилятором и компоновщиком, и было с первого стандарта. И тем не менее, этой простой функции не хватает в языке. Я считаю, что это связано с некой случайной исторической эволюцией языка.
Во всяком случае, я бы пошел для простой функции оболочки, показанной в первую очередь. 🙂
Других решений пока нет …