[英]C++ count_if function - couldn't infer template
我正在尝试使用C ++的count_if
函数来查看std::string
中有多少个十六进制数字。 当我尝试以下内容时:
string s = "123abc";
cout << count_if(s.begin(), s.end(), isxdigit) << endl;
我收到以下错误:
count.cpp:14:13: error: no matching function for call to 'count_if'
cout << count_if(s.begin(), s.end(), isxdigit) << endl;
^~~~~~~~
/usr/include/c++/4.2.1/bits/stl_algo.h:448:5: note: candidate template ignored: couldn't infer
template argument '_Predicate'
count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
但是,当我使用::isxdigit
,程序会编译并运行。 我知道在全局范围内使用isxdigit
可以预先设置::
但是我不确定为什么它在这种情况下会有所帮助。 我也认为它与C ++语言环境有关,但我对它们并不太熟悉。
谢谢!
C标准库中有一个函数int isxdigit(int)
(头文件<ctype.h>
,C ++等效头文件<cctype>
)。 这可以在count_if
明确使用。
如果包含<ctype.h>
,则此函数最终在全局命名空间中。 如果包含<cctype>
,则保证将其放在命名空间std
; 但由于它是一个C库函数,因此允许您的C ++标准库(实现)将其放入全局命名空间。
另一方面,C ++标准库(header <locale>
)中有一个函数模板 isxdigit
。 这只是放在命名空间std
。
你得到这个错误的原因是因为你可能有一个using namespace std;
在某处,或以其他方式使<locale>
std::isxdigit
可见。 然后,名称isxdigit
引用一组重载函数。 由于有多个候选者,并且count_if
接受了许多候选者,因此编译器现在无法实现哪种重载。
您可以指定使用哪个重载,例如,使用static_cast<int(*)(int)>(&isxdigit)
。
当您使用::isxdigit
,只找到一个函数,因此编译器知道其类型并可以推导出模板参数。
比手动选择重载更有用的解决方案是使用带有泛型函数调用操作符的函数对象:
struct Isxdigit
{
template<class T>
bool operator()(T const& p) const
{
using std::isxdigit;
return isxdigit(p);
}
};
int main()
{
string s = "123abc";
cout << count_if(s.begin(), s.end(), Isxdigit()) << endl;
}
这会自动选择适当的过载。
在C ++ 1y中,您可以使用泛型lambda:
int main()
{
string s = "123abc";
cout << count_if(s.begin(), s.end(), [](auto p){ return isxdigit(p); })
<< endl;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.