From what I understand, you want to have a common test to find out if a class has a specific member function. This can be done in C ++ using SFINAE . In C ++ 11, this is pretty simple as you can use decltype :
template <typename T> struct has_size { private: template <typename U> static decltype(std::declval<U>().size(), void(), std::true_type()) test(int); template <typename> static std::false_type test(...); public: typedef decltype(test<T>(0)) type; enum { value = type::value }; };
If you use C ++ 03, this is a bit more complicated due to the lack of decltype , so you need to use sizeof instead:
template <typename T> struct has_size { private: struct yes { int x; }; struct no {yes x[4]; }; template <typename U> static typename boost::enable_if_c<sizeof(static_cast<U*>(0)->size(), void(), int()) == sizeof(int), yes>::type test(int); template <typename> static no test(...); public: enum { value = sizeof(test<T>(0)) == sizeof(yes) }; };
Of course, this uses Boost.Enable_If , which can be an undesirable (and unnecessary) dependency. However, write enable_if yourself is simple:
template<bool Cond, typename T> enable_if; template<typename T> enable_if<true, T> { typedef T type; };
In both cases, the signature of the test<U>(int) method is visible only if U has a size method, because otherwise the evaluation is either decltype or sizeof (depending on the version you are using), which then removes this method from consideration (from for SFINAE . Long expressions std::declval<U>().size(), void(), std::true_type() are abuses of the C ++ comma operator, which will return the last expression from a comma-separated list, so this ensures that the type known as std::true_type for the C ++ 11 variant (and sizeof evaluates int for the C ++ 03 variant). void() in the middle is only there to convince There is no weird overload; the comma operator interferes with the evaluation.
Of course, this will return true if T has a size method that can be called without arguments, but does not give any guarantees regarding the return value. I assume that you probably want to find only those methods that do not return a void. This can easily be done with a slight modification to the test(int) method:
// C++11 template <typename U> static typename std::enable_if<!is_void<decltype(std::declval<U>().size())>::value, std::true_type>::type test(int); //C++03 template <typename U> static typename std::enable_if<boost::enable_if_c<sizeof(static_cast<U*>(0)->size()) != sizeof(void()), yes>::type test(int);