Skip to content

Instantly share code, notes, and snippets.

@fenbf
Created February 9, 2016 20:33
Show Gist options
  • Save fenbf/d2cd670704b82e2ce7fd to your computer and use it in GitHub Desktop.
Save fenbf/d2cd670704b82e2ce7fd to your computer and use it in GitHub Desktop.
C++ SFINAE example: how to detect if a class contains ToString method
// SFINAE, enable_if example
// based on http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence
#include <iostream>
#include <type_traits>
class ClassWithToString
{
public:
std::string ToString() { return "description of ClassWithToString object"; }
};
class ClassNoToString
{
public:
int a;
};
// SFINAE test
template <typename T>
class HasToString
{
private:
typedef char YesType[1];
typedef char NoType[2];
template <typename C> static YesType& test( decltype(&C::ToString) ) ;
template <typename C> static NoType& test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(YesType) };
};
template<typename T>
typename std::enable_if<HasToString<T>::value, std::string>::type
CallToString(T * t) {
/* something when T has toString ... */
return t->ToString();
}
/*
template<typename T>
typename std::enable_if<std::is_class<T>::value, std::string>::type
CallToString(T * t) {
return "a class without ToString() method!";
}
*/
std::string CallToString(...)
{
return "undefined object, cannot call ToString() method here";
}
int main(int argc, char *argv[])
{
std::cout << HasToString<ClassWithToString>::value << std::endl;
std::cout << HasToString<ClassNoToString>::value << std::endl;
std::cout << HasToString<int>::value << std::endl;
ClassWithToString c1;
std::cout << CallToString(&c1) << std::endl;
ClassNoToString c2;
std::cout << CallToString(&c2) << std::endl;
int c3 = 0;
std::cout << CallToString(&c3) << std::endl;
return 0;
}
@jheruty
Copy link

jheruty commented Jul 29, 2020

Clean implementation. Note that this only works for public members, since decltype will fail on private members. This can either be a bug or a feature depending on what you're trying to do.

@ilqvya
Copy link

ilqvya commented Apr 24, 2021

good

@archibald1418
Copy link

Clean and concise, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment