Skip to content

Instantly share code, notes, and snippets.

@fenbf
Created February 9, 2016 20:33
Show Gist options
  • Select an option

  • Save fenbf/d2cd670704b82e2ce7fd to your computer and use it in GitHub Desktop.

Select an option

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

jheruty commented Jul 29, 2020

Copy link
Copy Markdown

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

ilqvya commented Apr 24, 2021

Copy link
Copy Markdown

good

@archibald1418

Copy link
Copy Markdown

Clean and concise, thank you!

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