rel*_*xxx 1 c++ overloading wchar-t wstring implicit-conversion
我有以下代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
我得到:
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 &)'
Run Code Online (Sandbox Code Playgroud)
wstring 和 wchar_t * 之间不应该有任何隐式转换(应该吗?),那么为什么会出现这些歧义呢?
先感谢您
第四个重载需要移至列表顶部,以便它首先出现。
前三个重载都尝试调用第四个重载,但它尚未声明,因此在重载解析期间未找到它。
std::wstring确实有一个转换构造函数,允许const wchar_t*将 a 隐式转换为 a std::wstring。这是造成歧义的部分原因,尽管真正的问题是重载的顺序。
虽然前三个重载中的任何调用都不会调用第四个match重载,但第三个重载中的调用仅存在歧义。原因如下:
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)
Run Code Online (Sandbox Code Playgroud)
(1)match中的调用没有歧义,因为此时只有一个名为visible 的函数。match
(2)match中的调用没有歧义,因为(2)比(1)更适合参数:
要调用(2),第一个参数需要调用std::wstring转换构造函数,第二个参数是完全匹配的。
要调用(1),需要为两个参数调用转换构造函数。
(3)出现歧义是因为三个可用的重载都不是“最佳”:
要调用(1),需要为两个参数调用转换构造函数。
要调用(2),需要为第一个参数调用转换构造函数,并且第二个参数完全匹配。
要调用(3),第一个参数是完全匹配的,但需要为第二个参数调用转换构造函数。
这三个中没有一个明显优于其他两个。
如果将(4)移动到在其他重载之前声明,则它对于(1)、(2)和(3)中进行的调用无疑是更好的匹配,因为两个参数在所有三种情况下都是完全匹配的。