When writing a function that accepts a predicate function, such as the one below; how can you ensure the predicate function is valid (i.e. the return type of operator()
is valid)?
template <typename Predicate>
std::vector<SomeType> SearchList( Predicate func )
{
std::vector<SomeType> vecResults;
for( const auto& someObj : someTypeList )
{
if( func( someObj ) )
vecResults.emplace_back( someObj );
}
return vecResults;
}
Looking around at the type-traits facility in C++11, I've discovered std::is_convertible<From,To>
, which looks like it should help, although I'm not sure how to use it to check there is a suitable implicit conversion from operator()
to bool
. The only things I could think of were:
static_assert( std::is_convertible<Predicate(SomeType), bool>::value, "Predicate type must be convertible to bool" );
Or:
static_assert( std::is_convertible<Predicate::operator()(SomeType), bool>::value, "Predicate type must be convertible to bool" );
But neither of these seem to look correct to me.
You could use:
#include <utility> // For std::declval<>()
static_assert(
std::is_convertible<decltype(func(std::declval<SomeType>())), bool>::value,
"Predicate's return type must be convertible to bool");
If you only have the type Predicate
or do not want to use func
in the expression:
static_assert(
std::is_convertible<
decltype(std::declval<Predicate&>()(std::declval<SomeType>())),
bool>::value,
"Predicate's return type must be convertible to bool");