重载 wstring 和 wchar_t * 中的类似转换

发布于 2024-10-30 06:31:11 字数 915 浏览 1 评论 0原文

我有以下代码:

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

先感谢您

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╰◇生如夏花灿烂 2024-11-06 06:31:11

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

前三个重载都尝试调用第四个重载,但它尚未声明,因此在重载解析期间未找到它。


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) 因为这两个参数在所有三种情况下都是完全匹配的。

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.

温馨耳语 2024-11-06 06:31:11

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

There are, because C++ uses some 1 parameter constructors as implicit converters. For example, std::wstring must have a wstring(wchar_t*) constructor

影子是时光的心 2024-11-06 06:31:11

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);
    }

   .........
}

wstring (it's just a basic_string<>) has the ctor with a single const wchar_t* parameter. That enables implicit conversion from const wchar_t* to wstring. From the header file,

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);
    }

   .........
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文