Vikram
Vikram

Reputation: 1775

Vector of Pointers C++ Boost Serialization Error

namespace featurelib
{
    typedef vector<float*> HOG_List;    
}
    void saveFeaturesFile(vector<featurelib::HOG_List> &features, string filename){
        ofstream out(filename.c_str());
        stringstream ss;
        boost::archive::binary_oarchive oa(ss);
        oa << features;
        out << ss.str();
        out.close();
    }

This is my code snippet and I am trying to save vector<featurelib::HOG_List> into a binary file using Boost Serialization. But this results in an error:

error C4308: negative integral constant converted to unsigned type

But when I remove the pointer i.e

typedef vector<float> HOG_List; 

The code compiles and works fine. However I need to find a way to save vectors of typedef vector<float*> HOG_List; to binary files using Boost

Upvotes: 1

Views: 421

Answers (1)

sehe
sehe

Reputation: 393134

Why would you ever have a vector of float*?

Besides that, pointers are special to serialization because of object tracking: http://www.boost.org/doc/libs/1_60_0/libs/serialization/doc/special.html#objecttracking and potential polymorphism/aliasing.

Because float is a primitive type polymorphism is not a concern here. However, for the same reason object tracking would be unwieldy and has been disabled:

By default, data types designated primitive by the Implementation Level class serialization trait are never tracked. If it is desired to track a shared primitive object through a pointer (e.g. a long used as a reference count), It should be wrapped in a class/struct so that it is an identifiable type. The alternative of changing the implementation level of a long would affect all longs serialized in the whole program - probably not what one would intend.

This, in turn, means that the serialization library doesn't know how to deal with float*


I'd suggest you use a ptr_vector or really think why you need the pointers.

What do the pointers mean? Replace them with an abstraction that captures the semantics. E.g. if the float* is /really/ the address of the first element in array like float[32] then redefine your HOG_List as being e.g.

typedef std::vector<std::vector<float> > HOG_List;

If you have to cater for "unowned" arrays, you could make do with something like GLS'd array_view

struct float_array_view {
     float* base;
     size_t n;
};

typedef std::vector<float_array_view> HOG_List;

NOTE that in such a case you will have to define a way to deserialize it (serialize using boost::serialization::make_array). Because there's no way the library could know how to allocate the base*.

See also:

There are more potentially relevant posts here: https://stackoverflow.com/search?q=user%3A85371+boost+make_array

Upvotes: 1

Related Questions