I\'ve written this functor to perform an and operation (&&):
// unary functor; performs \'&&\'
template
I suggest not abusing std::function
and taking normal generic parameters instead. Treat std::function
as a type-erased container for callable objects of a particular signature (see https://stackoverflow.com/a/11629125/46642 for more details).
// unary functor; performs '&&'
template <typename X, typename Y>
struct AND
{
X x;
Y y;
template <typename XX, typename YY>
AND(XX&& xx, YY&& yy)
: x(std::forward<XX>(xx)), y(std::forward<YY>(yy)) {}
template <typename T>
auto operator() ( const T &arg ) -> decltype(x(arg) && y(arg))
{ return x(arg) && y(arg); }
};
template <typename T>
using Decay = typename std::decay<X>::type;
// helper
template <typename X, typename Y>
AND<Decay<X>, Decay<Y>> And(X&& xx, Y&& yy)
{
return AND<Decay<X>, Decay<Y>>(std::forward<X>(xx), std::forward<Y>(yy));
}
The problem is that there's no way to deduce T
in this context. Let's look at it from the compiler's perspective:
template <typename T>
AND<T> And(function<bool (const T&)> xx, function<bool (const T&)> yy)
// Later, invoked as:
And( is_odd, is_big )
"Hm, no T
is specified on the call, I will have to deduce it. What's the argument? is_odd
, which is decayed to type int (*)(int)
. Now, I would have to instantiate std::function<bool (const T&)>
for all possible T
values and see for which/if any it can be constructed from type int (*)(int)
. Well, there's infinitely many of them. Not gonna do this."
It would work if you specified the T
tempalte argument explicitly:
return any_of( first, last, And<int>( is_odd, is_big ) );
Live example
Note that this holds even if you changed is_odd
and is_big
to match the function
signature exactly (returning bool
and taking const int&
). It's the deduction that's the problem.