Just recently I came across a nice appliance of the C++ SFINAE pattern, when I was trying to write some unit tests (using googletest) for a C++ template metaprogramming class that creates a type hierarchy of a given typelist.

Here is a simplified version of what I wanted to test:


#include "gtest/gtest.h"
class A {};
class B {};
class C {}; 

typedef TypeList<A, TypeList<B> > BaseClasses;

class Foo :
	public InheritFrom<BaseClasses>
{};

TEST(InheritFrom, TestCorrectInheritance)
{
	Foo f; A* a = &f; //this will work
	C* c = &f; //this will cause a compile time error
} 

The goal is to test, if InheritFrom really creates the correct class hierarchy. For it I create an instance of class Foo and try to convert a pointer to it to a pointer of the desired base class. Line 16 will cause a compiler error, because of an invalid pointer conversion. Well, compile time error are not particulary useful when it comes to unit testing, so there has to be a different solution. To give you the big picture, the following code contains the implementation of TypeList and InheritFrom:

/** End marker for TypeList */
struct NullType;

template<typename HEAD, typename TAIL = NullType>
struct TypeList
{
	typedef HEAD head;
	typedef TAIL tail;
};

template<typename BASE_TYPES>
struct InheritFrom;

/** Recursive inheritance */
template<typename HEAD, typename TAIL>
struct InheritFrom<TypeList<HEAD, TAIL> > :
	public HEAD,
	public InheritFrom<TAIL>
{};

/** Termination of recursive inheritance */
template<typename HEAD>
struct InheritFrom<TypeList<HEAD, NullType> > :
	public HEAD
{};

After some research I found that Boost contains a function is_base_of that could do the job, but for all who are interested in how a SFINAE based solution looks like, here it is along with the updated unit test:

/** Checks if C is a base class of T */
template<typename T, typename C>
class HasBaseClass
{
    struct yes { char y; };
    struct no  { char n[2]; };

    static yes hasBaseClass(C*);
    static no  hasBaseClass(...);
public:
    enum { value = (sizeof(yes) == sizeof(hasBaseClass((T*)0L))) };
};

TEST(BaseTypes, TestCorrectInheritance)
{
    EXPECT_TRUE(static_cast<bool>(HasBaseClass<Foo, A>::value));
    EXPECT_FALSE(static_cast<bool>(HasBaseClass<Foo, C>::value));
}

The basic idea is, as mentioned above, to make use of implicit pointer conversion. HasBaseClass takes two template parameters, T (the type we want to test) and C (the desired base class). Line 8 declares a static function that takes a pointer to C and returns type yes, that has been declared in line 5. Note that the helper types yes and no have a different size (if you measure it with sizeof). The overloaded version of hasBaseClass in line 9, which will be used by the compiler whenever it cannot use the one from line 8, returns type no. Now, in line 11, we compare the size of the result of hasBaseClass called with an argument of type pointer to T with the size of the type yes and store the result in an enum named value. This result can be used to write tests without causing compile time errors. The beauty of the SFINAE concept it, that it does not create any overhead to your software. Note that the whole class HasBaseClass consists solely of declarations, not a single instance is created or function is defined. The use of sizeof takes place at compile time, too, so it won’t affect your actual program. I hope you find the SFINAE concept as fascinating as I do and perhaps this example does help you in applying it more frequently.

The complete code is available here.