Skip to content

Instantly share code, notes, and snippets.

@Jiwan
Last active November 3, 2018 05:49
Show Gist options
  • Save Jiwan/160a64a5d1d25e4bdf6b to your computer and use it in GitHub Desktop.
Save Jiwan/160a64a5d1d25e4bdf6b to your computer and use it in GitHub Desktop.
C++11 example 2 SFINAE
#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