为什么这个函数模板特化不能编译?

时间:2015-10-02 14:21:40

标签: c++ templates template-specialization

我正在尝试在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不同,因为在该链接中,他们试图返回与模板不同的类型,这是一个非常特殊的情况,我不想在这里做。)

2 个答案:

答案 0 :(得分: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*/>开头的内容都是不正确的。

答案 1 :(得分: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";
}