Wednesday, September 23, 2009

Episode Nine: Erasing the Concrete

Type erasure is a technique that allows to store and operate objects of different types that fulfill a given concept. It can be seen as non-intrusively introducing an abstract base class to every type that provides a common interface. It turns a wide variety of types into one type.

Two big exponents of type erasure are Boost.Any [1] and Boost.Function [2]. Boost.Any is like C# and Java's Object base class, except it has value semantics. Boost.Function implements a generalized callback type that can be used to store arbitrary function pointers and function objects.



Its implementation defines a placeholder, which provides the abstract interface; and a holder template class that stores the concrete object, in terms of which implements the placeholder's interface (the type is not really erased, but pushed further away).

An example of type erasure that creates a single type to operate on every object that can be incremented follows.

· Placeholder:
class placeholder
{
public:
virtual ~placeholder() {}
virtual placeholder* clone() const = 0;
virtual void increment() = 0;
};
· Holder:
template< typename T > class holder : public placeholder
{
public:
explicit holder( T const& value ) : _held( value ) {}
holder* clone() const { return new holder( _held ); }
void increment(){ ++_held; }

private:
T _held;
};
· Incrementable:
class incrementable
{
public:
template< typename T > incrementable( T const& value )
: _content( new holder< T >( value ) ){}

incrementable( incrementable const& that )
: _content( that._content->clone() ){}

~incrementable() { delete _content; }

void swap( incrementable& rhs )
{
std::swap( _content, right._content );
return (*this);
}

template< typename T > incrementable& operator=( T const& rhs )
{
incrementable( rhs ).swap( *this );
return (*this);
}
incrementable& operator=( incrementable rhs )
{
rhs.swap( *this );
return (*this);
}

void increment(){ _content->increment(); }

private:
placeholder* _content;
};

With the given definition, an object of type incrementable can be used to hold and increment any arithmetical types, pointers, iterators, and every other type that implements the pre-increment operator.

[1] http://www.boost.org/doc/html/any.html
[2] http://www.boost.org/doc/html/function.html

No comments:

Post a Comment