C++ count_if 函数 - 无法推断模板

标签 c++

我正在尝试使用 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++ 语言环境有关,但我对它们不太熟悉。

谢谢!

最佳答案

有一个函数int isxdigit(int)在 C 标准库中( header <ctype.h> ,C++ 等效 header <cctype> )。这可以在 count_if 中明确使用.

如果您包括 <ctype.h> , 这个函数在全局命名空间中结束。如果包括 <cctype> , 它保证放在命名空间 std 中;但由于它是一个 C 库函数,您的 C++ 标准库(实现)也可以将其放入全局命名空间。

另一方面,有一个函数模板 isxdigit在 C++ 标准库中( header <locale>)。这只放入命名空间 std .


你得到这个错误的原因是因为你可能有一个 using namespace std;某处,或以其他方式制作std::isxdigit来自 <locale>可见的。然后,名字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;
}

关于C++ count_if 函数 - 无法推断模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20019636/

相关文章:

又是 C++ 函数指针。语法困惑

c++ - 相当于 Windows 上的 random(3)?

c++ - C/C++ 中对位数组的两种操作

c++ - 坚持从文本文件中删除 "\r"! C++

c++ - 无法让 Helgrind/DRD 使用 C++11 线程

c++ - OpenCL - 从缓冲区读取时出现 CL_INVALID_VALUE

c++ - fp :precise vs. fp: 严格性能

c++ - 如何使用 OpenMP 并行化此循环?

c++ - 有没有办法让这个 C++14 递归模板在 C++17 中更短?

c++ - C++ 比较和交换例程中的无锁数据结构