简体   繁体   中英

How to use isnan as a predicate function to std::find_if (c++11)

I have a piece of code that is operating on a std::vector<double> cats and is doing something like this:

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

this compiles under gcc before 4.3 but no longer compiles with gcc 4.7.2. I get an error like this:

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

How can I get this to compile under newer gcc? And preferably also under the older gcc? Without getting rid of stl and manually writing the loop of course. If it's not possible to do both, the new gcc would suffice and I would leave both implementations in there with a #define .

The overload you actually want is not a template in GCC 4.7, it is just a normal function with this signature:

bool isnan(double);

(There is a template, but SFINAE means it only applies to integral types.)

But in previous versions it was a template, so there isn't an easy portable way to take its address.

Since you've said C++11, you can use a lambda and let the body of the lambda do overload resolution to find the right overload (or template specialization):

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

Otherwise for C++03 you could provide your own forwarding wrapper:

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

In C++11, isnan is a set of three overloads for the different floating point types float , double , long double . You can resolve the overload you want by using the cast syntax:

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

Of course, the use of a lambda as suggested by Jonathan might be clearer for maintainers, if your target platforms all support lambdas.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM