Dissecting Code

Wednesday, July 7, 2010

Restricting template types: Requiring member functions

It is desired that a class parametrized by, say a single type argument, T, only be instantiated by types that provide a particular function ( say void foo() )



// T must have void T::foo()


template <class T>
class RequireFoo
{
}

A petty solution:


template <class T>
class RequireFoo
{
public:
~RequireFoo(){ void (T::*fptr)() = &T::foo; }
};

The above solution will throw a compiler error if non foo having class is used as a parameter.

A much cooler solution: Move this check out to a template class


template <class T>
class CheckFoo
{
public:
CheckFoo(){ void (T::*fptr) = &T::foo; }
}

template< class T >
class RequireFoo: CheckFoo<T>
{
}

Here, the responsibility of checking for foo is checked in base class CheckFoo's constructor which is automatically called when RequireFoo is instantiated.
Ideas from: http://www.gotw.ca/publications/mxc++-item-4.htm

Complete Code:



#include <iostream>

class HasFoo
{
public:
void foo(){}
};

class NoFoo
{
};

template <class T>
class CheckFoo
{
public:
CheckFoo(){ void (T::*fptr)() = &T::foo; }
};

template <class T>
class RequireFoo: CheckFoo<T>
{
public:
};

int main()
{
RequireFoo< HasFoo > t;
return 0;
}


Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]



<< Home