I want to be able to evaluate whether a function accepts one argument of type int, and whether it returns void. To that end I used std::conjunction
since I believed it was supposed to short-circuit and not evaluate the second ill-formed expression in case the function is not callable with one argument of type int, but for some reason I get a compiler error:
#include <iostream>
#include <type_traits>
template<typename Function>
struct oneArgVoid
{
static constexpr bool value = std::conjunction_v<std::is_invocable<Function, int>, std::is_void<std::invoke_result_t<Function, int>>>;
};
int main()
{
auto l1 = [](auto x) {};
std::cout << oneArgVoid<decltype(l1)>::value << "\n";
auto l2 = [](auto x) {return 1; };
std::cout << oneArgVoid<decltype(l2)>::value << "\n";
auto l3 = [](auto x, auto y) {};
std::cout << oneArgVoid<decltype(l3)>::value << "\n";
return 0;
}
Note that if oneArgVoid
is not called on l3
the code compiles. Live demo: https://godbolt.org/z/8BUfpT
I do not use boost, so I cannot use mpl::eval_if
. But I thought that std::conjunction
was supposed to short circuit here, am I wrong?
Considering HolyBlackCat's suggestion, here's something even stranger: https://godbolt.org/z/2SUij-
Determines whether Fn can be invoked with the arguments ArgTypes... to yield a result that is convertible to R.
– Pointblank