How do I determine if a type is callable with only const references?

后端 未结 6 1813
清酒与你
清酒与你 2021-02-04 13:08

I want to write a C++ metafunction is_callable that defines value to be true, if and only if the type F has the function cal

6条回答
  •  别那么骄傲
    2021-02-04 13:33

    (with apologies to Kerrek for using his answer as a starting point)

    EDIT: Updated to handle types without any operator() at all.

    #include 
    
    template 
    struct Callable
    {
    private:
      static int tester[1];
      typedef char                      yes;
      typedef struct { char array[2]; } no;
    
      template 
      static char sfinae(decltype(std::declval()(std::declval())) (G::*pfn)(Brg)) { return 0; }
    
      template 
      static char sfinae(decltype(std::declval()(std::declval())) (G::*pfn)(Brg) const) { return 0; }
    
      template 
      static yes test(int (&a)[sizeof(sfinae(&G::operator()))]);
    
      template 
      static no test(...);
    
    public:
      static bool const value = sizeof(test(tester)) == sizeof(yes);
    };
    
    struct Foo
    {
      int operator()(int &) { return 1; }
    
    };
    
    struct Bar
    {
      int operator()(int const &) { return 2; }
    };
    
    struct Wazz
    {
      int operator()(int const &) const { return 3; }
    };
    
    struct Frob
    {
      int operator()(int &) { return 4; }
      int operator()(int const &) const { return 5; }
    };
    
    struct Blip
    {
      template
      int operator()(T) { return 6; }
    };
    
    struct Boom
    {
    
    };
    
    struct Zap
    {
      int operator()(int) { return 42; }
    };
    
    #include 
    int main()
    {
      std::cout << "Foo(const int &):  " << Callable::value << std::endl
                << "Foo(int &):        " << Callable::value << std::endl
                << "Bar(const int &):  " << Callable::value << std::endl
                << "Bar(int &):        " << Callable::value << std::endl
                << "Zap(const int &):  " << Callable::value << std::endl
                << "Zap(int&):         " << Callable::value << std::endl
                << "Wazz(const int &): " << Callable::value << std::endl
                << "Wazz(int &):       " << Callable::value << std::endl
                << "Frob(const int &): " << Callable::value << std::endl
                << "Frob(int &):       " << Callable::value << std::endl
                << "Blip(const int &): " << Callable::value << std::endl
                << "Blip(int &):       " << Callable::value << std::endl
                << "Boom(const int &): " << Callable::value << std::endl
                << "Boom(int&):        " << Callable::value << std::endl;
    }
    

    Demo: http://ideone.com/T3Iry

提交回复
热议问题