首页 > 解决方案 > 对重载函数 find_first_not_of 的模糊调用

问题描述

错误 C2668: 'std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<:wchar_t>>::find_first_not_of' : 对重载函数的模糊调用

我在 Visual Studio 2013 中收到此错误,但在 MinGW 中没有。我能用这个做什么?

我尝试添加cache.std::wstring::find_first_not_of,但这没有帮助。

我的代码:

wstring cache = key.GetExpandStringValue(L"Path");
int empregnul = 0;
if(cache.find_first_not_of('\0') == wstring::npos)
{
    empregnul = 1;
}

标签: c++visual-studiovisual-c++visual-studio-2013

解决方案


我认为 MSVC 通过拒绝您的代码而不符合标准,至少从 C++14 开始。您使用的版本早于 C++14,因此显然不支持它,但更高版本的 MSVC 仍然会产生相同的歧义错误,即使给出了/std:c++14or/std:c++latest/permissive-标志,请参阅 hhttps://godbolt.org/z /fQA4YD。但还要注意此答案末尾关于 MSVC 更新版本的评论。

MSVC 似乎认为'\0'可以转换为空指针值,因为它是一个空指针常量

这将使作为参数的重载和find_first_not_of作为wchar_t参数的重载const wchar_t*同样匹配。

您可以看到这是 MSVC 通过将字符值更改为零以外的任何值(例如'a',在这种情况下 MSVC 认为调用是明确的)来对歧义进行推理的。

但是,在CWG 问题 903作为缺陷报告的决议之后,C++14 标准(最终草案)和后续标准的[conv.ptr]/1中的相关段落说:

空指针常量是值为零或 std::nullptr_t 类型的纯右值的整数文字 ([lex.icon]) 。

'\0'字符文字,而不是整数文字。因此它不是空指针常量,不能转换为指针,使得调用明确。

在 CWG 问题 903 解决之前,任何整数类型和零值的右值常量表达式都是空指针常量,因此在这种情况下,MSVC 给出歧义是正确的。但这并不能解释较新版本和 C++14(或更高版本)标志中的行为。

这可以通过使用L'\0'而不是来解决'\0',因为L'\0'它具有类型wchar_t,因此它与期望的重载wchar_t 完全匹配,而期望的重载const wchar_t*需要转换(假设甚至允许转换),从而使前者更好地匹配并解决歧义。

无论如何,上面提到的修复也是您应该做的,即使没有错误(尽管在这种特定情况下并不重要)。您不想charwchar_t. 使用wchar_t/时,wstring请始终L在字符文字和字符串文字前面添加以赋予它们正确的类型。


正如@RaymondChen 在此问题下的评论中指出的那样,MSVC 的更新版本(在 Godbolt 上不可用)在给出标志时确实实现了 CWG 903 的解析/permissive-,请参阅Implicit conversion of integer constant expressions to null pointer


推荐阅读