我尝试使用std::isgraph
中的<cctype>
作为find_if
中的谓词。但是编译器错误地说:
错误:没有匹配函数来调用'find_if(__ gnu_cxx :: __ normal_iterator&lt; const char *,std :: basic_string&lt; char&gt;&gt;,__ gn_cxx :: __ normal_iterator&lt; const char *,std :: basic_string&lt; char&gt;&gt; ;,&lt; 未解析的重载函数类型&gt;)'
我使用过using namespace std;
,根据我的理解,全局命名空间中会显示两个isgraph
个函数。因此::isgraph
或简称isgraph
应该含糊不清,std::isgraph
不应该含糊不清。相反,使用::isgraph
是正常的,而std::isgraph
则不然。
有人可以解释我错过了什么吗?一些相关问题是What are the function requirements to use as the predicate in the find_if from the <algorithm> library?和C++ using standard algorithms with strings, count_if with isdigit, function cast。但他们没有回答为什么明确指定std::
仍未解析std
命名空间中的函数。
修改:
#include <cctype>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
int main()
{
string root_line = "hello";
auto ind = distance(root_line.begin(), find_if(root_line.begin(), root_line.end(), std::isgraph));
cout << ind;
return 0;
}
我使用版本4.8.4的g ++ -std = c ++ 11编译了上面的代码
答案 0 :(得分:3)
std::isgraph
已超载。
要解决歧义,可以将其转换为相关的函数指针类型。
但是为了正确使用它,参数应该转换为unsigned char
,所以最好定义一个包装函数:
using Byte = unsigned char;
auto is_graphical( char const ch )
-> bool
{ return !!isgraph( Byte( ch ) ); }
请注意,这仅适用于单字节编码,并且它取决于C级别的当前区域设置(请参阅setlocale
)。
答案 1 :(得分:0)
std::isgraph
中定义了<cctype>
,&lt; locale&gt;中有std::isgraph
个不同的定义。使用重载函数作为仿函数可能会很麻烦,因为编译器很难确定您想要的函数版本。您可以通过转换或使用@ Cheersandhth.-Alf
#include <cctype>
#include <algorithm>
#include <string>
#include <iostream>
int main()
{
std::string root_line = "hello";
auto ind = std::distance(root_line.begin(), std::find_if(root_line.begin(), root_line.end(), static_cast<int(*)(int)>(std::isgraph)));
std::cout << ind;
}