I have following code:
inline bool match(const std::wstring & text1, const std::wstring & text2)
{
return match(text1.c_str(), text2.c_str());
}
inline bool match(const std::wstring & text1, const wchar_t * text2)
{
return match(text1.c_str(), text2);
}
inline bool match(const wchar_t * text1, const std::wstring & text2)
{
return match(text1, text2.c_str());
}
inline bool match(const wchar_t * text1, const wchar_t * text2)
{
return !wcscmp(text1, text2);
}
and I am getting:
error C2666: 'match' : 3 overloads have similar conversions
1> could be 'bool match(const wchar_t *,const std::wstring &)'
1> or 'bool match(const std::wstring &,const wchar_t *)'
1> or 'bool match(const std::wstring &,const std::wstring &)'
There should not be any implicit conversion between wstring and wchar_t * (should it?), so why these ambiguities?
Thank you in advance
The fourth overload needs to be moved to the top of the list so it appears first.
The first three overloads all try to call the fourth overload, but it hasn't been declared yet, so it isn't found during overload resolution.
std::wstring
does have a converting constructor that allows a const wchar_t*
to be implicitly converted to a std::wstring
. That is partially responsible for the ambiguity, though the real issue is the ordering of the overloads.
While the fourth overload won't be called by any of the calls to match
in the first three overloads, there is only an ambiguity for the call in the third overload. Here's why:
inline bool match(const std::wstring & text1, const std::wstring & text2) // (1)
inline bool match(const std::wstring & text1, const wchar_t * text2) // (2)
inline bool match(const wchar_t * text1, const std::wstring & text2) // (3)
inline bool match(const wchar_t * text1, const wchar_t * text2) // (4)
There is no ambiguity for the call to match
in (1) because there is only one function named match
visible at that point.
There is no ambiguity for the call to match
in (2) because (2) is a better match for the arguments than (1):
To call (2), the first argument requires a call to the std::wstring
converting constructor and the second argument is an exact match.
To call (1), the converting constructor would need to be called for both arguments.
The ambiguity occurs for (3) because none of the three available overloads are "best":
To call (1), the converting constructor would need to be called for both arguments.
To call (2), the converting constructor would need to be called for the first argument and the second argument is an exact match.
To call (3), the first argument is an exact match but the converting constructor would need to be called for the second argument.
None of these three is unambiguously better than the other two.
If (4) is moved to be declared before the other overloads, it will be an unambiguously better match for the call made in (1), (2), and (3) because both arguments would be an exact match in all three cases.