PrevUpHomeNext

BOOST_DECLARE_IS_CALLABLE

The BOOST_DECLARE_IS_CALLABLE macro extends the functionality 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.


PrevUpHomeNext