2015-10-02 2 views
2

Я пытаюсь специализировать templatised функцию внутри templatised класса. Он отлично работает, пока я не добавлю специализацию: тогда он больше не компилируется.Почему эта специализированная функция не компилируется?

Вот упрощенный пример того, что такие вещи, что я пытаюсь сделать:

template <typename TString, typename TStringStream, typename TChar> 
class TestClass 
{ 
public: 
    template <typename T> 
    static T convert(const TChar* text); 
}; 


//This specialisation doesn't compile 
template <typename TString, typename TStringStream, typename TChar> 
template <> 
inline bool TestClass<TString, TStringStream, TChar>::convert(const TChar* text) 
{ 
    return strcmp(text, "true"); 
} 


template <typename TString, typename TStringStream, typename TChar> 
template <typename T> 
T TestClass<TString, TStringStream, TChar>::convert(const TChar* text) 
{ 
    TStringStream textStream(text); 
    T result; 
    textStream >> result; 
    return result; 
} 


void main() 
{ 
    TestClass<RString, RStringstream, char>::convert<bool>("0"); 
} 

Это ошибка компилятора Visual Studio 2010 возвращается, когда я пытаюсь скомпилировать это:

error C2244: 'TestClass<TString,TStringStream,TChar>::convert' : unable to match function definition to an existing declaration 
    definition 
    'bool TestClass<TString,TStringStream,TChar>::convert(const TChar *)' 
    existing declarations 
    'T TestClass<TString,TStringStream,TChar>::convert(const TChar *)' 

Что я здесь делаю неправильно?

(Этот вопрос отличается от this one, потому что в этой связи они пытаются вернуть другой тип из того, что шаблон, очень особый случай, который я не пытаюсь сделать здесь.)

+0

Возможный дубликат [Переопределение типа возвращаемого в шаблоне функции специализации] (http://stackoverflow.com/questions/15911890/overriding-return-type-in-function-template-specialization) – NathanOliver

+1

Мои вопрос другой, потому что в этой ссылке они пытаются вернуть другой тип из того, что шаблон, очень частный случай, который я не пытаюсь здесь делать. – Oogst

+0

ick, не делайте 'void main' – o11c

ответ

3

Ваш источник недопустим C++, template<> не может следовать списку параметров шаблона.

Шаблон TestClass<TString, TStringStream, TChar>::convert также может быть полностью специализированным, но только для данного экземпляра TestClass<TString, TStringStream, TChar>. Такие, как:

template <> 
template <> 
inline bool TestClass<RString, RStringstream, char>::convert<bool>(const char* text) 
{ 
    return text == "true"; 
} 
+0

Это работает, спасибо! :) – Oogst

+0

Если вам нужна частичная специализация, вам нужно сделать это через класс. Или вы могли бы просто сделать перегрузку. – o11c

+0

Перегрузка не работает, если это возвращаемое значение изменяется, пока параметры остаются неизменными. – Oogst

4

[temp.expl.spec]/16 В явном объявлении специализации для члена шаблона класса или шаблона члена, который появляется в области пространства имен, шаблон-член и некоторые из его вмещающих шаблонов классов могут оставаться неспециализированными, за исключением того, что объявление не должны явно специализировать шаблон члена класса, если его встроенные шаблоны классов также явно не специализируются ... [Пример:

template <class Y> template <> 
void A<Y>::B<double>::mf2() { } // ill-formed; B<double> is specialized but 
           // its enclosing class template A is not 

- конец пример]

В принципе, все, что начинается с template<something> template</*nothing*/> плохо сформирован.