Double templated function overload fails

136 views Asked by At

I have a template class, having various template functions. One of them need to be overloaded (a couple of times).

Basically - if my class would not be a template, these would be my function(s):

class OtherClass
{
public:
    template<class T> T foo(T &t, const std::string &trash);
};

template<class T>
T OtherClass::foo(T &t, const std::string &trash)
{
    return t; //...
}

template<>
std::wstring OtherClass::foo<std::wstring>(std::wstring &w, const std::string &trash)
{
    return w; //...
}

This:

int main(...)
{
    int i = 0;
    std::wstring w;

    OtherClass o;
    i = o.foo(i, std::string(""));
    w = o.foo(w, std::string(""));
}

My template class looks like:

template<class MStr>
class OtherClass
{
public:
    template<class TVal> TVal foo(TVal &t, const MStr &trash);
};

//Which leads to the function definition

template<class MStr>
template<class TVal>
TVal OtherClass<MStr>::foo(TVal &t, const MStr &trash)
{
    return t; //...
}

What I wanted to have... (int as example)

template<class MStr>
template<>
int OtherClass<MStr>::foo<int>(int &t, const MStr &trash)
{
    return t; //...
}

Welcome in the land of
C2768: illegal use of explicit template arguments
and
C2244: unable to match function definition

1>...\test\main.cpp(74): error C2768: 'OtherClass<MStr>::foo' : illegal use of explicit template arguments
1>...\test\main.cpp(74): error C2768: 'OtherClass<MStr>::foo' : illegal use of explicit template arguments
1>...\test\main.cpp(74): error C2244: 'OtherClass<MStr>::foo' : unable to match function definition to an existing declaration
1>          definition
1>          'int OtherClass<MStr>::foo<int>(int &,const MStr &)'
1>          existing declarations
1>          'TVal OtherClass<MStr>::foo(TVal &,const MStr &)'
1>
1>Build FAILED.

I have been testing, and looking for hours in Google and Stackoverflow... so far the best answer/question, which does not seem to be applicable for me was this.

Q: Is there anyone who could point me in the right direction, or has a fix for it, in order to solve this issue ?

1

There are 1 answers

1
TartanLlama On BEST ANSWER

A way to sidestep this issue is to just declare that int version as an overload rather than an template specialization:

template<class MStr>
class OtherClass
{
public:
    template<class TVal> TVal foo(TVal &t, const MStr &trash);
    int foo(int &t, const MStr &trash);
};

Then defined as:

template<class MStr>
int OtherClass<MStr>::foo(int &t, const MStr &trash)
{
    return t; //...
}

It's not particularly pretty if you have many overload cases, but it probably beats any other solutions.