HiveBrain v1.2.0
Get Started
← Back to all entries
snippetcppCritical

How can you check whether a templated class has a member function?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
hasyouhowfunctioncheckclasswhethertemplatedmembercan

Problem

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
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.

Solution

Yes, with SFINAE you can check if a given class does provide a certain method. Here's the working code:

#include 

struct Hello
{
    int helloworld() { return 0; }
};

struct Generic {};    

// SFINAE test
template 
class has_helloworld
{
    typedef char one;
    struct two { char x[2]; };

    template  static one test( decltype(&C::helloworld) ) ;
    template  static two test(...);    

public:
    enum { value = sizeof(test(0)) == sizeof(char) };
};
    
int main(int argc, char *argv[])
{
    std::cout ::value ::value << std::endl;
    return 0;
}


I've just tested it with Linux and gcc 4.1/4.3. I don't know if it's portable to other platforms running different compilers.

Code Snippets

#include <iostream>

struct Hello
{
    int helloworld() { return 0; }
};

struct Generic {};    

// SFINAE test
template <typename T>
class has_helloworld
{
    typedef char one;
    struct two { char x[2]; };

    template <typename C> static one test( decltype(&C::helloworld) ) ;
    template <typename C> static two test(...);    

public:
    enum { value = sizeof(test<T>(0)) == sizeof(char) };
};
    
int main(int argc, char *argv[])
{
    std::cout << has_helloworld<Hello>::value << std::endl;
    std::cout << has_helloworld<Generic>::value << std::endl;
    return 0;
}

Context

Stack Overflow Q#257288, score: 392

Revisions (0)

No revisions yet.