Boost logo

Boost :

From: Matthew Vogt (mvogt_at_[hidden])
Date: 2004-04-21 22:17:10


Previously, I posted that I was unhappy with the way access to an archive's
save methods could be controlled. This was because the class the eventually
invokes the 'save' method of an oarchive is a library class, and has to be
given friend access.

I have now realised that this was trying to control access the wrong way;
instead of making the type-specific 'save' method private, the type-specific
overload of 'operator<<' should made private to prevent general access for
saving a given type.

Here is a basic test that shows what I had been trying to achieve, now
working correctly:

//---------------------------------------------------------------------------

#include <boost/serialization/access.hpp>
#include <boost/archive/common_oarchive.hpp>

class float_storer
{
    friend class boost::serialization::access;

private:
    float f;

    template<class Archive>
    void serialize(Archive& archive, const unsigned int version)
    {
        archive & f;
    }
};

namespace archive = boost::archive;

class simple_oarchive :
    public archive::common_oarchive<simple_oarchive>
{
    friend class archive::common_oarchive<simple_oarchive>;
    friend class archive::save_access;

    // Do nothing with library internal types
    simple_oarchive& operator<< (const archive::class_id_type&)
        { return *this; }
    simple_oarchive& operator<< (const archive::class_id_optional_type&)
        { return *this; }
    simple_oarchive& operator<< (const archive::class_id_reference_type&)
        { return *this; }
    simple_oarchive& operator<< (const archive::class_name_type&)
        { return *this; }
    simple_oarchive& operator<< (const archive::version_type&)
        { return *this; }
    simple_oarchive& operator<< (const archive::object_id_type&)
        { return *this; }
    simple_oarchive& operator<< (const archive::object_reference_type&)
        { return *this; }

    // Save any type that gets here
    template<typename T>
    void save(const T& t) {}

    // Only allow 'float_storer' to store floats
    friend class float_storer;

    simple_oarchive& operator<< (const float& t)
    {
        archive::save(*This(), t);
        return *This();
    }

public:
    // Allow anyone to store ints
    simple_oarchive& operator<< (const int& t)
    {
        archive::save(*This(), t);
        return *This();
    }

    simple_oarchive& operator<< (const float_storer& t)
    {
        archive::save(*This(), t);
        return *This();
    }
};

int main(int, char**)
{
    simple_oarchive oa;

    int i;
    oa << i;

    float f;
    oa << f; // I want this to fail

    float_storer fs;
    oa << fs; // I want this to succeed

    return 0;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk