Reputation:
I have two templates.
The first one for an integer
template <class T>
T myMin(T a, T b)
{
return (a < b) ? a : b;
}
The second one for a string
template <class TypeFrom, class TypeTo>
TypeTo convert(TypeFrom &from)
{
return static_cast<TypeTo>(from);
}
template <>
std::string convert<std::wstring, std::string>(std::wstring &from)
{
return std::string(from.begin(), from.end());
}
The first template I can use without using the types
int c = myMin(1,2);
But for the second template I have to use the types
std::string st = convert<std::wstring, std::string>(sw);
I can not use it without:
std::string st = convert(sw); // this fails with the error "no accordance found for convet<TypeFrom, TypeTo>(wstring)"
Any idea why is that?
Upvotes: 1
Views: 89
Reputation: 37606
Template argument cannot be deduced from return type of a function. You could swap the order of your template parameter to be able to do type deduction of the input argument(s):
template <class TypeTo, class TypeFrom >
TypeTo convert(TypeFrom &from)
{
return static_cast<TypeTo>(from);
}
template <>
std::string convert<std::string, std::wstring>(std::wstring &from)
{
return std::string(from.begin(), from.end());
}
// Partial deduction
std::string st = convert<std::string>(sw);
Basically, you cannot do convert(sw)
because it may be ambiguous in many cases, e.g.:
// Call without using the return value
convert(sw);
// Call with return value sent to an overloaded function
void g (std::string) ;
void g (int) ;
g(convert(sw));
AFAIK, the same restriction applies to overloaded function (for the same reason). You cannot have in C++
(and in many languages such as Java), the following:
int f ();
float f ();
Actually, if you think about it, even your call is ambiguous because std::string
has multiple constructors, so should I do:
std::string st = convert <std::string> (sw) ; // Copy constructor
std::string st = convert <const char *> (sw) ; // Constructor from const char *
The main idea is that while it may not be ambiguous for you (while would I convert to const char *
instead of directly std::string
?), it is ambiguous for the compiler, and it is not the compiler role to make that kind of choices.
Upvotes: 2