重载 wstring 和 wchar_t * 中的类似转换
我有以下代码:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
第四个重载需要移至列表顶部,以便它首先出现。
前三个重载都尝试调用第四个重载,但它尚未声明,因此在重载解析期间未找到它。
std::wstring
确实有一个转换构造函数,允许将const wchar_t*
隐式转换为std::wstring
。这是造成歧义的部分原因,尽管真正的问题是重载的顺序。虽然前三个重载中对
match
的任何调用都不会调用第四个重载,但第三个重载中的调用仅存在歧义。原因如下:(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 aconst wchar_t*
to be implicitly converted to astd::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:There is no ambiguity for the call to
match
in (1) because there is only one function namedmatch
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.
有,因为 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
wstring(它只是一个 basic_string<>)具有带有单个 const wchar_t* 参数的 ctor。这可以实现从 const wchar_t* 到 wstring 的隐式转换。从头文件中,
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,