Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- struct A {};
- std::string to_string(const A&)
- {
- return "I am a A!";
- }
- // Type B with a serialize method.
- struct B
- {
- std::string serialize() const
- {
- return "I am a B!";
- }
- };
- // Type C with a "wrong" serialize member (not a method) and a to_string overload.
- struct C
- {
- std::string serialize;
- };
- std::string to_string(const C&)
- {
- return "I am a C!";
- }
- struct D : A
- {
- std::string serialize() const
- {
- return "I am a D!";
- }
- };
- struct E
- {
- struct Functor
- {
- std::string operator()(){
- return "I am a E!";
- }
- };
- Functor serialize;
- };
- // Structures are good as they expose everything in public!
- template <class T> struct hasSerialize
- {
- // For the compile time comparison.
- typedef char yes[1];
- typedef yes no[2];
- // This helper struct permits us to check two properties of a template argument.
- template <typename U, U u> struct reallyHas;
- // Two overloads for yes: one if for the signature of a normal method, one is for the signature of a const method.
- template <typename C> static yes& test(reallyHas<std::string (C::*)(), &C::serialize>* /*unused*/) { }
- template <typename C> static yes& test(reallyHas<std::string (C::*)() const, &C::serialize>* /*unused*/) { }
- // The famous C++ sink-hole.
- // Note that sink-hole must be templated too as we are testing test<T>(0).
- template <typename> static no& test(...) { /* dark matter */ }
- // The constant used as a return value for the test.
- enum { value = sizeof(test<T>(0)) == sizeof(yes) };
- };
- template <class T> bool testHasSerialize(const T& /*t*/) { return hasSerialize<T>::value; }
- template<bool B, class T = void>
- struct enable_if {};
- template<class T>
- struct enable_if<true, T> { typedef T type; };
- template <class T> typename enable_if<hasSerialize<T>::value, std::string>::type serialize(const T& obj)
- {
- return obj.serialize();
- }
- template <class T> typename enable_if<!hasSerialize<T>::value, std::string>::type serialize(const T& obj)
- {
- return to_string(obj);
- }
- int main() {
- A a;
- B b;
- C c;
- std::cout << serialize(a) << std::endl;
- std::cout << serialize(b) << std::endl;
- std::cout << serialize(c) << std::endl;
- return 0;
- }
Add Comment
Please, Sign In to add comment