1

我有以下代码:

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 * 之间不应该有任何隐式转换(应该吗?),那么为什么会有这些歧义呢?

先感谢您

4

3 回答 3

4

第四个重载需要移动到列表的顶部,以便它首先出现。

前三个重载都试图调用第四个重载,但它还没有被声明,所以在重载解析期间没有找到它。


std::wstring确实有一个转换构造函数,它允许 aconst wchar_t*隐式转换为 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)

match(1)中的调用没有歧义,因为此时只有一个名为matchvisible 的函数。

match对in (2)的调用没有歧义,因为(2)(1)更适合参数匹配:

  • 要调用(2),第一个参数需要调用std::wstring转换构造函数,第二个参数是完全匹配的。

  • 要调用(1),需要为两个参数调用转换构造函数。

(3)出现歧义,因为三个可用的重载都不是“最好的”:

  • 要调用(1),需要为两个参数调用转换构造函数。

  • 要调用(2),需要为第一个参数调用转换构造函数,并且第二个参数是完全匹配的。

  • 要调用(3),第一个参数是完全匹配的,但需要为第二个参数调用转换构造函数。

这三个中没有一个明显优于其他两个。

如果将(4)移动到在其他重载之前声明,那么对于(1)(2)(3)中的调用,它将是一个明确更好的匹配,因为这两个参数在所有三种情况下都是完全匹配的.

于 2011-04-04T17:04:41.093 回答
2

有,因为 C++ 使用一些 1 参数构造函数作为隐式转换器。例如,std::wstring 必须有一个 wstring(wchar_t*) 构造函数

于 2011-04-04T17:06:01.590 回答
0

wstring(它只是一个 basic_string<>)具有带有单个 const wchar_t* 参数的 ctor。这可以实现从 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);
    }

   .........
}
于 2011-04-04T17:11:30.453 回答