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
(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