Специализация шаблона: проблема определения неинлайн-функции


Следующий код компилируется правильно.

#include <string>

template <typename T, typename U>
class Container
{
private:
    T value1;
    U value2;
public:
    Container(){}
    void doSomething(T val1, U val2);
};

template<typename T, typename U>
void Container<typename T, typename U>::doSomething(T val1, U val2)
{
    ; // Some implementation
}

template <>
class Container<char, std::string>
{
private:
    char value1;
    std::string value2;
public:
    Container(){}
    void doSomething(char val1, std::string val2)
    {
        ; // Some other implementation
    }
};

Но если я попытаюсь определить void doSomething(char val1, std::string val2) снаружи, я получу следующую ошибку.

#include <string>

template <typename T, typename U>
class Container
{
private:
    T value1;
    U value2;
public:
    Container(){}
    void doSomething(T val1, U val2);
};

template<typename T, typename U>
void Container<typename T, typename U>::doSomething(T val1, U val2)
{
    ; // Some implementation
}

template <>
class Container<char, std::string>
{
private:
    char value1;
    std::string value2;
public:
    Container(){}
    void doSomething(char val1, std::string val2);
};

template<>
void Container<char,std::string>::doSomething(char val1, std::string val2)
{
    ; // Some other implementation
}

Ошибка:

Ошибка 1 ошибка C2910: 'Container:: doSomething' : не может быть явно специализированные c:usersbharanidocumentsvisual студия 2005проектышаблонышаблон специализацияtemplatespecializationtest.cpp 35

Какую ошибку я совершаю?

Спасибо.

1 2

1 ответ:

Вы явно не специализируете функцию-член. Но вы определяете функцию-член явной специализации (класс template -). Это другое, и вам нужно определить его как

inline void Container<char,std::string>::doSomething(char val1, std::string val2)
{
    ; // Some other implementation
}

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

Ты имейте шаблон в вашей явной специализации, ваш синтаксис должен быть использован:

template <>
class Container<char, std::string>
{
private:
    char value1;
    std::string value2;
public:
    Container(){}

    template<typename T, typename U>
    void doSomething(T val1, U val2) { /* primary definition */ }
};

template<>
inline void Container<char,std::string>::doSomething(char val1, std::string val2)
{
    ; // Some other implementation
}

У вас также есть ошибка в вашем первом коде. Вам нужно определить определение out of class следующим образом, без "typename" в списке аргументов шаблона класса

template<typename T, typename U>
void Container<T, U>::doSomething(T val1, U val2) 
{
    ; // Some implementation
}