Reputation: 19
I am currently trying to write a template specialization for a function that showes the power of different values. my code is :
#include <iostream>
using namespace std;
template <class T>
T myfunc(T x)
{
return x*x;
}
template<>
string myfunc<string>(string ss)
{
return (ss+ss);
}
int main()
{
cout<<myfunc("test")<<endl;
return 0;
}
Compilation fails with:
error C2784: 'std::_String_iterator<_Mystr> std::operator +(_String_iterator<_Mystr>::difference_type,std::_String_iterator<_Mystr>)' : could not deduce template argument for 'std::_String_iterator<_Mystr>' from 'std::string'
Can you please help me detect where exactly is the problem?
Upvotes: 1
Views: 99
Reputation: 2829
You need to pass the function a string, not a char array. Try myfunc(string("test"))
To expand a little - the choice of which template / template specialisation to use when a function is called is called template argument deduction.
You want myfunc to be called, however the type of test is char[5] (null character on the end). Therefore the template argument is 'deduced' to be char[5].
Often, char[] can be cast to string implicitly (this is deprecated i believe) in a call to a fully specialised function (not a template function). This implicit cast is because, as user1274223 pointed out, a std::string has a constructor with signature string(const char *) and this constructor is not explicit! That is helpful for when we want to pretend c strings (char*) are easily interchangeable with cplusplus strings (std::string
), however it can be confusing in these types of situations.
The other work around is myfunc<string>("test")
, because here the template argument is passed directly, and char[] can be cast implicitly.
Upvotes: 5
Reputation: 58
As others already said. in addition, I think you need to
#include <string>
in which the operator+ for strings and string itself declared the error you get is your compiler try to match all the other operator+ in and failed.
Upvotes: 0
Reputation: 229593
A template specialization is unnecessary in this case, you should just overload the function:
std::string myfunc(const std::string &ss)
{
return (ss+ss);
}
This way calling it as myfunct("test")
will work.
For a all the details why function template specializations are usually not usefu you can have a look at Herb Sutter's article Why Not Specialize Function Templates?
Upvotes: 1