C++ Boost

Serialization

smart_cast


Motivation

To cast from one type to another related type, C++ provides the following operators:
static_cast<T *<>(U *)
static_cast<T &<>(U &)

dynamic_cast<T *<>(U *)
dynamic_cast<T &<>(U &)
These rules can make it difficult to use casting with a function template argument. Consider the following example:

#include <boost/serialization/smart_cast.hpp>

struct top {
};

struct base1 : public top {
    bool is_storable() const {
        return true;
    }
    virtual ~base1();
};

struct base2 {
    virtual ~base2();
};

struct derived1 :
    public base1
{
    derived1();
};

struct derived2 :
    public base1, 
    public base2
{
    derived2();
};

template<class T>
bool is_storable(T &t){
    // what type of cast to use here?

    // this fails at compile time when T == base2
    // return static_cast<base1 &>(t).is_storable();

    // this fails at compile time when T == top
    // otherwise it works but cannot optimize inline function call
    // return dynamic_cast<base1 &>(t).is_storable();

    // this always works - and is guaranteed to generate the fastest code !
    return (boost::smart_cast_reference<base1 &>(t)).is_storable();
}

int main(){
    derived1 d1;
    top & t1 = d1;
    derived2 d2;
    base2 & b2 = d2;

    bool result;
    result = is_storable(d1);   
    result = is_storable(d2);   
    result = is_storable(b2);
    result = is_storable(b2);
    result = is_storable(t1);
    return 0;
}
The serialization library includes a mix of classes which use both static polymorphism (CRTP) and dynamic polymorphism via virtual functions. smart_cast was written to address the more problematic manifestations of the situation exemplified above.

Usage

The following syntax is supported:

smart_cast<Target *, Source *>(Source * s);
smart_cast<Target *>(Source * s);
smart_cast<Target &, Source &>(Source & s);
Note that the above syntax doesn't include

smart_cast<Target & >(Source & s)
but the same functionality is supported with the following special syntax

smart_cast_reference<Target &>(Source & s)

Requirements

smart_cast can be used only on compilers that support partial template specialization or on types for which the macro BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(<type>) has been applied.

© Copyright Robert Ramey 2002-2004. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)