BOOST_DECLARE_IS_CALLABLE Макро расширяет фанктональность, обеспечиваемую BOOST_DECLARE_HAS_MEMBER, и позволяет объявить черту, которая затем позволила бы интроспектировать существование функции названного члена класса, вызывающей поставляемую подпись.
Например, следующие декларации вводят черты<local::can_call_funop
>и<local::can_call_func
>:
namespace { namespace local
{
BOOST_DECLARE_IS_CALLABLE(can_call_funop, operator());
BOOST_DECLARE_IS_CALLABLE(can_call_func, func);
}}
Характеристики позволяют проверить, имеет ли поставляемый класс соответственно<operator()
>и<func()
>функции-члены, вызывающиеся с указанной подписью:
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));
Как видно из примера, признаки проверяют наличиевызывающейфункции члена, ноне обязательно указанной подписи. Пожалуйста, проверьте библиотекуBoost.TTIдля последнего.