#include <iostream>
#include <type_traits>
#include <boost/tti/has_member_function.hpp>
#include <boost/function_types/result_type.hpp>
struct Interface
{
std::string interface()const
{
return "interface";
}
};
struct my_interface
{
std::string get_my_interface()const
{
return "get_my_interface";
}
};
struct myInterfaceType
{
std::string myInterface()const
{
return "myInterface";
}
};
namespace foo
{
namespace detail
{
BOOST_TTI_HAS_MEMBER_FUNCTION(interface)
BOOST_TTI_HAS_MEMBER_FUNCTION(get_my_interface)
BOOST_TTI_HAS_MEMBER_FUNCTION(myInterface)
}
template<typename Interface>
struct GenericInterface
{
template<typename T = Interface>
typename std::enable_if< detail::has_member_function_interface<std::string (T::*)()const>::value,std::string >::type query_interface()const
{
return i.interface();
}
template<typename T = Interface>
typename std::enable_if< detail::has_member_function_get_my_interface<std::string (T::*)()const >::value, std::string>::type query_interface()const
{
return i.get_my_interface();
}
template<typename T = Interface>
typename std::enable_if< detail::has_member_function_myInterface<std::string (T::*)()const >::value, std::string >::type query_interface()const
{
return i.myInterface();
}
void print()
{
std::cout << query_interface() << "\n";
}
private:
Interface i;
};
}
int main(int argc, char *argv[])
{
foo::GenericInterface<Interface> gInterface;
foo::GenericInterface<my_interface> gmy_interface;
foo::GenericInterface<myInterfaceType> gmyInterface;
gInterface.print();
gmy_interface.print();
gmyInterface.print();
std::cout << std::boolalpha <<foo::detail::has_member_function_get_my_interface<std::string (my_interface::*)()const>::value << std::endl;
std::cout << std::boolalpha <<foo::detail::has_member_function_interface<myInterfaceType,std::string>::value << std::endl;
std::cout << std::boolalpha << foo::detail::has_member_function_interface<std::string (Interface::*)()const>::value << std::endl;
static_assert(foo::detail::has_member_function_interface<std::string (Interface::*)()const>::value,"fail");
std::cout << "Hello World!" << std::endl;
return 0;
}