How to check at compile-time if a function that can be called with a specific set of arguments exists?

后端 未结 2 1165
独厮守ぢ
独厮守ぢ 2021-01-01 05:18

This is different from checking if a specific function is defined. Here, for this check to return true, the function has to be defined and passing the arguments

2条回答
  •  不知归路
    2021-01-01 06:08

    #define overload_set(F)\
      struct { auto operator()(auto&&...args)const\
        ->decltype(F(std::forward(args)...))\
         { return (F(std::forward(args)...)); }\
      }
    

    this takes a token F and generates an overload set type for F.

    It is not quite perfect: it only does perfect forwarding with SFINAE tests. But it is close.

    We then use this:

    templatestruct can_invoke:std::false_type{};
    template
    struct can_invoke()(std::declval()...)
      ))
    >:std::true_type{};
    

    Mixing them we get:

    typedef overload_set(Foo) Foo_overloads;
    std::cout << can_invoke::value<<"\n";
    

    will print 1 if Foo(3,2) works. As noted, this is limited by failures of perfect forwarding.

    You can also pass Foo_overloads{} to functions expecting a function object, and it will dispatch at the call site instead of doing it when you pass the function object.

提交回复
热议问题