Thursday, August 13, 2009

Overloading static_cast?

If you have been using C++ long enough, you'll likely have come across situations where you needed your own type conversions. In most cases, this is as simple as adding an overloaded conversion operator to your class, and it will work fine with the regular static_cast.

But what if you are using templates and would like to allow conversion to the same class with a different template type? You can of course provide a templated conversion operator that converts to YourClass< T >.

Here is an alternative solution: Just write your own casting operator. Here is an example:

template< typename T >
struct Vector2d
{
T _x, _y, _z;

Vector2d( T x, T y, T z );
};

template< typename Dst, typename Src >
Vector2d< Dst > geomConvert( const Vector2d< Src >& src )
{
return Vector2d< Dst > (
static_cast< Dst >( src._x ),
static_cast< Dst >( src._y ),
static_cast< Dst >( src._z )
);
}

You can the use the function like this:

Vector2d< float > floatVec = ...;
Vector2d< double > doubleVec = geomConvert< double >( floatVec );

Note that in order for this to work, the destination type must be the first template parameter. If you specify it second, the compiler won't automatically fill in the source parameter for you and you will have to explicitly specify both the source and the destination type in your template arguments.

In most cases, providing a custom overloaded operator is just fine, but in some cases, this solution might come in handy or provide a cleaner interface. It also saves some typing, since you only have to specify the template parameter, not the entire class name including the template parameter.

It is also a way to force explicit conversion, for instance if you are dealing with a lot of data, like and array of 10000 * 200000 floats. Conversion to double then requires calling a specialized function. If you just overloaded the conversion operator, someone not too familiar with your API might carelessly use static_cast or use implicit conversion on your data, even though it causes very expensive data conversion and memory allocation routines to be called.

Hope this is useful, happy coding :)

No comments:

Post a Comment