Reputation: 28520
If you have something like this,
struct Foo {
};
constexpr auto pred = [](){
return Foo{};
};
calling std::not_fn(pred)
will fail to compile, expectedly.
However, adding an explicit
conversion operator
from Foo
to bool
,
struct Foo {
explicit operator bool() {
return true;
}
};
is enough to make std::not_fn(pred)
compile.
This at first seemed reasonable to me. But then I realiazed that:
std::function<bool(int)> f{std::not_fn(pred)}; // compiles
std::function<bool(int)> g{pred}; // fails to compile
I do see some reason for the permissiveness of std::not_fn
: based on its name, it is supposed to negate a predicate, so fair enough if it tries to convert the return type of the given function to bool
.
But why shouldn't std::function
adopt a similar policy? After all, given a function of type ConvertibleToFoo(Bar)
, what would be wrong in constructing a std::function<Foo(ConvertibleToBar)>
?
Or, if std::function
doesn't allow that, why does std::not_fn
allow it?
Indeed, it seems to me that the fact that std::not_fn
is able to act on functions that return a non-bool
-but-explicit
ly-convertible-to-bool
type is a happy (or not happy) side effect of the fact that it uses !
, in its implementation, in front of the return type of the provided function.
Interesting blog post from Arthur O’Dwyer regarding covariance and contravariance.
Upvotes: 5
Views: 94