Is it possible to write a template that changes behavior depending on if a certain member function is defined on a class?
Here's a simple example of what I would want to write:
template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}
So, if class T
has toString()
defined, then it uses it; otherwise, it doesn't. The magical part that I don't know how to do is the "FUNCTION_EXISTS" part.
The generic template that can be used for checking if some "feature" is supported by the type:
The template that checks whether there is a method
foo
that is compatible with signaturedouble(const char*)
Examples
http://coliru.stacked-crooked.com/a/83c6a631ed42cea4
MSVC has the __if_exists and __if_not_exists keywords (Doc). Together with the typeof-SFINAE approach of Nicola I could create a check for GCC and MSVC like the OP looked for.
Update: Source can be found Here
There are a lot of answers here, but I failed, to find a version, that performs real method resolution ordering, while not using any of the newer c++ features (only using c++98 features).
Note: This version is tested and working with vc++2013, g++ 5.2.0 and the onlline compiler.
So I came up with a version, that only uses sizeof():
Live demo (with extended return type checking and vc++2010 workaround): http://cpp.sh/5b2vs
No source, as I came up with it myself.
When running the Live demo on the g++ compiler, please note that array sizes of 0 are allowed, meaning that the static_assert used will not trigger a compiler error, even when it fails.
A commonly used work-around is to replace the 'typedef' in the macro with 'extern'.
Strange nobody suggested the following nice trick I saw once on this very site :
You have to make sure T is a class. It seems that ambiguity in the lookup of foo is a substitution failure. I made it work on gcc, not sure if it is standard though.
Here is my version that handles all possible member function overloads with arbitrary arity, including template member functions, possibly with default arguments. It distinguishes 3 mutually exclusive scenarios when making a member function call to some class type, with given arg types: (1) valid, or (2) ambiguous, or (3) non-viable. Example usage:
Now you can use it like this:
Here is the code, written in c++11, however, you can easily port it (with minor tweaks) to non-c++11 that has typeof extensions (e.g. gcc). You can replace the HAS_MEM macro with your own.
I wrote an answer to this in another thread that (unlike the solutions above) also checks inherited member functions:
SFINAE to check for inherited member functions
Here are some example from that solution:
Example1:
We are checking for a member with the following signature:
T::const_iterator begin() const
Please notice that it even checks the constness of the method, and works with primitive types, as well. (I mean
has_const_begin<int>::value
is false and doesn't cause a compile-time error.)Example 2
Now we are looking for the signature:
void foo(MyClass&, unsigned)
Please notice that MyClass doesn't has to be default constructible or to satisfy any special concept. The technique works with template members, as well.
I am eagerly waiting opinions regarding this.