2016-11-04 6 views
0

Я могу специализироваться конструкторы отлично:как специализироваться конструктор шаблона

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 во время установки() во время выполнения. Но это было бы аккуратно, если бы сам объект знал без посторонней помощи.

+0

Я не вижу причин для этого частичная специализация (даже если это разрешено). Поплавок будет преобразован в double или int неявно. –

+0

для моих реальных потребностей аргумент будет более сложным. Для простоты я сделал это POD. – edwinc

+0

@edwinc: Будет ли аргумент иметь оператор преобразования для целевого типа? – AndyG

ответ

1

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

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

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

protected: 
    TType _type; 
}; 

Demo

+0

Спасибо за ответ. В прошлом я делал частичную специализацию методов. Вы говорите, что это невозможно, если аргумент шаблона является значением? Мои реальные потребности, хотя и идут по строкам: – edwinc

+1

@edwinc, вы, вероятно, частично специализировали структуру. Это никогда не было возможным для методов. – AndyG