Search code examples
c++sfinaecompile-timeboost-hana

Boost.Hana test if lambda is callable with particular argument


I want to test if a callable lambda can be called with particular arguments by using Boost.Hana. The compiler complains that callable expects 0 arguments but 1 were provided. Isn't the if_ a compile time if that does compile depending on the condition is_callable?

Maybe someone has an idea of how to get the code to work.

#include <boost/hana.hpp>

int main(){

  namespace bh = boost::hana;

  auto is_callable = bh::is_valid([](auto&& callable, auto&& args) -> decltype(bh::unpack(args, callable)){});        

  auto callable = [](){};
  auto arg = 1;
  auto args = bh::make_tuple(arg);

  bh::if_(is_callable(callable, args),
                   [arg](auto callable){ callable(arg);},
                   [](auto callable){})(callable);

  return 0;
}

Solution

  • As Jason Rice mentioned in the comments, the reason this fails is that hana::unpack is not SFINAE friendly. The easiest way to work around this is to call the callable ourselves for hana::is_valid, using hana::unpack to unpack the arguments into the result of hana::is_valid:

    auto const is_callable = [](auto&& callable, auto&& args) {
        return bh::unpack(args,
            bh::is_valid([&callable](auto&&... args)
                -> decltype(callable(args...))
            {})
        );
    };
    

    Live demo on Compiler Explorer