I have a template where a function is overloaded so it can handle both an std::string
parameter and the type of parameter that the template gets instantiated with. This works fine except when the template is being instantiated with std::string
, since this results in two member functions with the same prototype. Thus, I have chosen to specialize that function for this particular case. However, it seems like the compiler (g++ 4.8.1
with flag -std=c++0x
) never gets to the point where the specialization is actually overriding the primary template and it complains about the ambiguous overload the before it seems to realize that it should use the specialization. Is there a way to get around this?
#include <iostream>
template<class T>
struct A {
std::string foo(std::string s) { return "ptemplate: foo_string"; }
std::string foo(T e) { return "ptemplate: foo_T"; }
};
template<> //Error!
std::string A<std::string>::foo(std::string s) { return "stemplate: foo_string"; }
int main() {
A<int> a; //Ok!
std::cout << a.foo(10) << std::endl;
std::cout << a.foo("10") << std::endl;
//A<std::string> b; //Error!
//std::cout << a.foo("10") << std::endl;
return 0;
}
This results in compile errors, even if I don't instantiate at all with std::string
(it seems that the compiler instantiates with std::string
as soon as it sees the specialization and that it, before it actually processes the specialization, complains about the ambiguous overload which the specialization, in turn, will "disambiguate").
Compiler output:
p.cpp: In instantiation of 'struct A<std::basic_string<char> >':
p.cpp:10:27: required from here
p.cpp:6:14: error: 'std::string A<T>::foo(T) [with T = std::basic_string<char>; std::string = std::basic_string<char>]' cannot be overloaded
std::string foo(T e) { return "ptemplate: foo_T"; }
^
p.cpp:5:14: error: with 'std::string A<T>::foo(std::string) [with T = std::basic_string<char>; std::string = std::basic_string<char>]'
std::string foo(std::string s) { return "ptemplate: foo_string"; }
^
I would like it to just skip through the implementation of foo()
in the primary template and use the specialization without considering the primary template foo()
. Could it be done somehow, maybe with non-type template parameters, or do I have to make a fully specialized class template for std::string
with all the code duplication it implies (I prefer not to use inheritance here)... Other suggestions?