Boost.Hana offers boost::hana::is_valid
to check whether a SFINAE-friendly expression is valid.
You can use it like this
struct Person { std::string name; };
auto has_name = hana::is_valid([](auto&& p) -> decltype((void)p.name) { });
Person joe{"Joe"};
static_assert(has_name(joe), "");
static_assert(!has_name(1), "");
However, there's a note about the argument to is_valid
being a nullary function:
To check whether calling a nullary function
f
is valid, one should use theis_valid(f)()
syntax. […]
How can I even use it by passing to it a nullary function? I mean, if a function is nullary, then how is its body gonna have any dependent context to which SFINAE can apply?
I think that maybe "lambda captures" might have something to do with the answer, but I can't really figure it out how.
Use case is that of checking that f
is actually nullary, eg
if constexpr (is_valid(f)()) {
f(); // Treat f as a "no args function"
} else if constexpr (is_valid(f, arg1)) {
f(arg1);
}
what the documentation says is that unlike functions of non zero arity, the is_valid
predicate can only be invoked in the form:
is_valid(f)(); // Invoking "is_valid(f)", i.e. no parentheses, does NOT
// check that f is a nullary function.
reminder: to check whether eg a 2 arguments function call is valid you can say:
is_valid(f, arg1, arg2);
// or
is_valid(f)(arg1, arg2)
Take for example the following Demo
void f0()
{
std::cout << "Ok f0\n";
}
void f1(int)
{
std::cout << "Ok f1\n";
}
template <class F>
void test(F fun)
{
if constexpr (hana::is_valid(fun)())
{
fun();
}
else if constexpr (hana::is_valid(fun, 2))
{
fun(2);
}
}
int main() {
test(f0);
test(f1);
}
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.