【问题标题】:Get pointer to function declared into namespace获取指向在命名空间中声明的函数的指针
【发布时间】:2014-07-28 13:53:40
【问题描述】:

我想计算std::string 中的空格。 std::count_if 的任务非常简单,所以我写了这段代码:

std::cout<<std::count_if(str.cbegin(), str.cend(), &std::isspace);

和...编译器错误(xcode):No matching function for call to 'count_if'

我改成:

std::cout<<std::count_if(str.cbegin(), str.cend(), &isspace);

并且编译器错误不再存在。

你能解释一下第一行有什么问题吗?当函数位于命名空间中时获取函数指针时我是否遗漏了什么?这是否与 ADL 相关,因为 isspacecount_if 来自同一个命名空间?

编辑:

完整的构建日志:

Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/algorithm:1097:1: 候选模板被忽略:无法推断模板参数 '_谓词'

【问题讨论】:

  • 我敢打赌,您显示的错误消息不是构建日志中的唯一消息。请显示完整的日志。
  • 您不能安全地这样做,因为std::isspace 可能会超载。同样不安全的是盲目地将chars 传递给它。您应该使用显式调用 std::isspace 的东西(例如 lambda),并将 char 转换为 unsigned char
  • @chris 我的第一个实现使用了 lambda,但我只是从 isspace 返回结果,这似乎有点矫枉过正。现在我很感兴趣,为什么当我没有完全限定函数时会有区别......

标签: c++ c++11 namespaces function-pointers


【解决方案1】:

错误与包含(顺序和/或存在)有关。

有两个std::isspace 函数,一个接受一个参数,另一个接受两个参数。第一个在&lt;cctype&gt; 中声明,第二个在&lt;locale&gt; 中声明。

int isspace ( int c );

template <class charT>
  bool isspace (charT c, const locale& loc);

通常,在 C++11 中,计数可以写成

std::count_if(str.cbegin(), str.cend(), [](char c) {
  return std::isspace(c, std::locale());
});

【讨论】:

  • @Felics 因为只有一个isspace
  • @Felics,cctype 没有模板参数,我认为您的错误暗示了这一点。
  • @Felics,因为std::isspace 仅在std 内重载。但是,在&lt;cctype&gt; 中,实现可以可选地将C 版本提升到全局命名空间。 &lt;locale&gt; 无法做到这一点。为了保证::isspace 存在,你需要包含&lt;ctype.h&gt; 或者自己提升它,但是&lt;ctype.h&gt; 已被弃用并且自己提升它是糟糕的编码风格,如果&lt;locale&gt; 中的那个也被提升是一个问题。
  • 您需要将char 更改为unsigned char 以避免可能的溢出问题。你也可以std::count_if(str.cbegin(), str.cend(), std::isspace&lt;unsigned char&gt;);
  • @Felics 哦,是的,没错。好吧,您可以在 lambda 中将 char c 更改为 unsigned char c
猜你喜欢
  • 1970-01-01
  • 2011-06-20
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多