3

我有一段代码在 a 上运行,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.

4

2 回答 2

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() );
于 2013-07-10T15:09:35.683 回答
5

在 C++11 中,isnan是一组针对不同浮点类型floatdouble、的三个重载long double。您可以使用强制转换语法解决您想要的重载:

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

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

于 2013-07-10T15:16:44.137 回答