как специализировать конструктор шаблонов

Я умею хорошо специализировать конструкторы:

template < typename TType >
class Field
{
public:
Field( const Msg& )
: _type( TType() )
{ }

protected:
TType    _type;
};

template < >
Field < double >::Field( const Msg& msg )
: _type( msg.extractDouble() )
{
}

template < >
Field < int >::Field( const Msg& msg )
: _type( msg.extractInt() )
{
}

Тем не менее, мне нужно сделать то же самое для шаблона, который принимает нетипичный аргумент, такой как:

template < const char* pszName, typename TType >
class Field
{
public:
Field( const Msg& )
: _type( TType() )
{ }

static void setup( const Descriptor& d ) { // called once to setup _nIndex based on Descriptor and pszName
static int  index() { return _nIndex; }

protected:
TType              _type;   // This class can only be sizeof TType in size

static int         _index;
};

template < >
Field < ??, ?? >::Field( const Msg& msg )     // This doesn't compile
: _type( msg.extractDouble( index() ) )
{
}

template < >
Field < ??, ?? >::Field( const Msg& msg )        // This doesn't compile
: _type( msg.extractInt( index() ) )
{
}

Есть ли хитрость, чтобы сделать это? Я думаю, я мог бы передать имя const char во время setup () во время выполнения. Но было бы здорово, если бы сам объект знал без посторонней помощи.

0

Решение

Проблема здесь в том, что вы не можете частично специализировать функции, а конструктор — это функция. Вы либо полностью их специализируете, либо нет.

Распространенным решением этой проблемы является использование тега диспетчеризации, однако в вашем конкретном случае это немного проще … использовать static_cast

template < typename TType, int n >
class Field
{
public:
Field( float f )
: _type( static_cast<TType>(f) )
{ }

protected:
TType    _type;
};

демонстрация

1

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

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