我有以下代码:
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);
}
我得到了:
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 &)'
wstring和wchar_t *之间不应该有任何隐式转换(应该吗?),为什么这些含糊不清?
提前谢谢
答案 0 :(得分:4)
需要将第四个重载移到列表顶部,使其首先出现。
前三个重载都试图调用第四个重载,但它尚未声明,因此在重载解析期间找不到它。
std::wstring
确实有一个转换构造函数,允许const wchar_t*
隐式转换为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)
(1)中对match
的调用没有歧义,因为此时只有一个名为match
的函数可见。
(2)中对match
的调用没有歧义,因为(2)比更适合参数? 1)强>:
要调用(2),第一个参数需要调用std::wstring
转换构造函数,第二个参数是完全匹配。
要调用(1),需要为两个参数调用转换构造函数。
(3)出现歧义,因为三个可用的重载都不是“最佳”:
要调用(1),需要为两个参数调用转换构造函数。
要调用(2),需要为第一个参数调用转换构造函数,第二个参数是完全匹配。
要调用(3),第一个参数是完全匹配,但需要为第二个参数调用转换构造函数。
这三者中没有一个明显优于其他两个。
如果移动(4)在其他重载之前声明,则在(1),中进行的调用将明确更好地匹配(2)和(3)因为这两个参数在所有三种情况下都是完全匹配的。
答案 1 :(得分:2)
有,因为C ++使用一些参数构造函数作为隐式转换器。例如,std :: wstring必须具有wstring(wchar_t *)构造函数
答案 2 :(得分:0)
wstring(它只是一个basic_string<>)的ctor带有一个const wchar_t *参数。这使得从const wchar_t *到wstring的隐式转换成为可能。从头文件
typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
// TEMPLATE CLASS basic_string
template<class _Elem, class _Traits, class _Ax>
class basic_string : public _String_val<_Elem, _Ax>
{
.........
basic_string(const _Elem *_Ptr) : _Mybase()
{ // construct from [_Ptr, <null>)
_Tidy();
assign(_Ptr);
}
.........
}