如何使用isnan作为std :: find_if的谓词函数(c ++ 11)

时间:2013-07-10 15:07:34

标签: c++ c++11 gcc4.7

我有一段代码在std::vector<double> cats上运行,并且正在执行以下操作:

std::find_if(cats.begin(), cats.end(), std::isnan<double>);

这在4.3之前的gcc下编译,但不再用gcc 4.7.2编译。我收到这样的错误:

error: no matching function for call to 'find_if(std::vector<double>::iterator, std::vector<double::iterator, <unresolved overloaded function type>)'

如何在新的gcc下编译?并且最好也在较旧的gcc下?没有摆脱stl并手动编写循环当然。如果不可能同时执行这两个操作,那么新的gcc就足够了,我会在两个实现中留下#define

2 个答案:

答案 0 :(得分:8)

您实际需要的重载不是GCC 4.7中的模板,它只是具有此签名的普通函数:

bool isnan(double);

(有一个模板,但SFINAE意味着它只适用于整数类型。)

但在以前的版本中它是一个模板,因此没有一种简单易用的方式来获取其地址。

既然您已经说过C ++ 11,那么您可以使用lambda并让lambda的主体执行重载决策以找到正确的重载(或模板特化):

std::find_if( cats.begin(), cats.end(), [](double d) { return std::isnan(d); } );

否则对于C ++ 03,您可以提供自己的转发包装器:

struct IsNan {
  double operator()(double d) const { return std::isnan(d); }
};
std::find_if( cats.begin(), cats.end(), IsNan() );

答案 1 :(得分:5)

在C ++ 11中,isnan是针对不同浮点类型floatdoublelong double的三个重载的集合。您可以使用强制转换语法解决所需的重载:

std::find_if(cats.begin(), cats.end(),
             static_cast<bool (*)(double)>(std::isnan));

当然,如果你的目标平台都支持lambdas,那么使用Jonathan建议的lambda对于维护者来说可能更清楚。