| Home | Libraries | People | FAQ | More

### BOOST_DECLARE_IS_CALLABLE

The BOOST_DECLARE_IS_CALLABLE macro extends the functonality provided by BOOST_DECLARE_HAS_MEMBER and allows to declare a trait which would then let introspect the existence of a named class member function callable with the supplied signature.

For example, the following declarations introduce `local::can_call_funop` and `local::can_call_func` traits:

    namespace { namespace local
    {
        BOOST_DECLARE_IS_CALLABLE(can_call_funop, operator());
        BOOST_DECLARE_IS_CALLABLE(can_call_func, func);
    }}

The traits allow to test if the supplied class has respectively `operator()` and `func()` member functions callable with the specified signature:

    namespace { namespace callable
    {
        struct  test1 { int  operator()(double, std::string) { return 0; }};
        struct  test2 { void operator()(double, std::string) {}};
        struct  test3 { void operator()(int) {}};
        struct  test4 { std::string operator()(int) const { return std::string(); }};
        struct  test5 { std::string operator()(int, std::string const& =std::string()) const { return std::string(); }};
        struct  test6 { template<typename T> std::string operator()(T) const { return std::string(); }};
        struct  test7 { template<typename T> T operator()(T) const  { return T(); }};

        struct  test11 { int  func(double, std::string) { return 0; }};
        struct  test12 { void func(double, std::string) {}};
        struct  test13 { void func(int) {}};
        struct  test14 { std::string func(int) const { return std::string(); }};
        struct  test15 { std::string func(int, std::string const& =std::string()) const { return std::string(); }};
        struct  test16 { template<typename T> std::string func(T) const { return std::string(); }};
        struct  test17 { template<typename T> T func(T) const { return T(); }};
    }}

    BOOST_TEST((local::can_call_funop<callable::test1, int (double, std::string)>::value == true));
    BOOST_TEST((local::can_call_funop<callable::test1, double (int, std::string)>::value == true));
    BOOST_TEST((local::can_call_funop<callable::test1, void (double, std::string)>::value == true));
    BOOST_TEST((local::can_call_funop<callable::test1, void (int, std::string)>::value == true));
    BOOST_TEST((local::can_call_funop<callable::test1, void (int, char const*)>::value == true));
    BOOST_TEST((local::can_call_funop<callable::test1, int (double, int)>::value == false));
    BOOST_TEST((local::can_call_funop<callable::test1, int (double)>::value == false));

    BOOST_TEST((local::can_call_funop<callable::test2, int  (double, std::string)>::value == false));
    BOOST_TEST((local::can_call_funop<callable::test2, void (double, std::string)>::value == true));
    BOOST_TEST((local::can_call_funop<callable::test2, void (   int, std::string)>::value == true));
    BOOST_TEST((local::can_call_funop<callable::test2, void (   int, char const*)>::value == true));

    BOOST_TEST((local::can_call_func<callable::test11, int (double, std::string)>::value == true));
    BOOST_TEST((local::can_call_func<callable::test11, double (int, std::string)>::value == true));
    BOOST_TEST((local::can_call_func<callable::test11, void (double, std::string)>::value == true));
    BOOST_TEST((local::can_call_func<callable::test11, void (int, std::string)>::value == true));
    BOOST_TEST((local::can_call_func<callable::test11, void (int, char const*)>::value == true));
    BOOST_TEST((local::can_call_func<callable::test11, int (double, int)>::value == false));
    BOOST_TEST((local::can_call_func<callable::test11, int (double)>::value == false));

    BOOST_TEST((local::can_call_func<callable::test12, int  (double, std::string)>::value == false));
    BOOST_TEST((local::can_call_func<callable::test12, void (double, std::string)>::value == true));
    BOOST_TEST((local::can_call_func<callable::test12, void (   int, std::string)>::value == true));
    BOOST_TEST((local::can_call_func<callable::test12, void (   int, char const*)>::value == true));

As it can be seen from the example the traits check for the existence of a callable member function but not necessarily of the specified signature. Please check the Boost.TTI library for the latter.