Last active
November 3, 2018 05:49
-
-
Save Jiwan/160a64a5d1d25e4bdf6b to your computer and use it in GitHub Desktop.
C++11 example 2 SFINAE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
}; | |
// Primary template, inherit from std::false_type. | |
// ::value will return false. | |
// Note: the second unused template parameter is set to default as std::string!!! | |
template <typename T, typename = std::string> | |
struct hasSerialize | |
: std::false_type | |
{ | |
}; | |
// Partial template specialisation, inherit from std::true_type. | |
// ::value will return true. | |
template <typename T> | |
struct hasSerialize<T, decltype(std::declval<T>().serialize())> | |
: std::true_type | |
{ | |
}; | |
template <typename T> typename std::enable_if<hasSerialize<T>::value, std::string>::type serialize(T& obj) | |
{ | |
return obj.serialize(); | |
} | |
template <typename T> typename std::enable_if<!hasSerialize<T>::value, std::string>::type serialize(T& obj) | |
{ | |
return to_string(obj); | |
} | |
int main() { | |
A a; | |
B b; | |
C c; | |
D d; | |
E e; | |
std::cout << serialize(a) << std::endl; | |
std::cout << serialize(b) << std::endl; | |
std::cout << serialize(c) << std::endl; | |
std::cout << serialize(d) << std::endl; | |
std::cout << serialize(e) << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment