views:

48

answers:

1

The following code compiles properly.

#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
    }
};

But if I try to define void doSomething(char val1, std::string val2) outside, I get the following error.

#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
}

Error:

Error 1 error C2910: 'Container::doSomething' : cannot be explicitly specialized c:\users\bharani\documents\visual studio 2005\projects\templates\template specialization\templatespecializationtest.cpp 35

What mistake do I commit?

Thanks.

+4  A: 

You are not explicitly specializing a member function. But you are defining the member function of an explicit (class template-) specialization. That's different, and you need to define it like

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

Note that the "inline" is important, because this is not a template and it is not implicitly inline if it is defined outside the class. It's needed to be inline to avoid duplicate linker symbols if you include the header into more than one translation unit.

Would you have a template in your explicit specialization, your syntax would have to be used:

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
}

You also have an error in your first code. You need to define the out of class definition like this, without "typename" in the argument list of the class template

template<typename T, typename U>
void Container<T, U>::doSomething(T val1, U val2) 
{
    ; // Some implementation
}
Johannes Schaub - litb
Thanks a lot! It helped!!
bdhar