Johannes Thoma
Johannes Thoma

Reputation: 1076

Conversion between std::vector subclass with custom allocator and std::vectors

I have an advanced C++ question: Suppose I have a mmap_allocator template class, which is a subclass of std::allocator template class and a mmappable_vector template class which is a subclass of std::vector template class:

    template <typename T>
    class mmap_allocator: public std::allocator<T> {
            ...
    };

    template <typename T, typename A = mmap_allocator<T> >
    class mmappable_vector: public std::vector<T, A> {
            ...
    };

What I can do is convert from a mmappable_vector (with an mmap_allocator) to a std::vector (with the standard allocator) using a function template:

    template <typename T>
    std::vector<T> to_std_vector(const mmappable_vector<T> &v)
    {
            return std::vector<T>(v.begin(), v.end());
    }

but the other way seems not to be possible:

    template <typename T>
    mmappable_vector<T> to_mmappable_vector(const std::vector<T> &v)
    {
            return mmappable_vector<T>(v.begin(), v.end());
    }

The problem when defining a constructor like:

    typedef typename std::vector<T, A>::iterator iterator;

    mmappable_vector(iterator from, iterator to):
                    std::vector<T,A>(from, to)
    {
    }

this uses iterators with the mmap_allocator and hence does not match the call in to_mmappable_vector. On the other hand defining a constructor:

    mmappable_vector(std::vector<T,std::allocator<T> > v):
            std::vector<T,std::allocator<T> >(v)
    {
    }

fails because the

    std::vector<T,std::allocator<T> > 

is not a base class of the mmappable vector.

How do I write a function template that converts std::vectors to mmappable_vectors? Is this possible at all within C++?

Thanks for any insights,

Upvotes: 1

Views: 799

Answers (1)

PiotrNycz
PiotrNycz

Reputation: 24412

You do not have template constructor in your mmappable_vector which takes two iterators of any type. Like this one:

template <typename T, typename A = mmap_allocator<T> >
    class mmappable_vector: public std::vector<T, A> {
      typedef std::vector<T, A> Base;
      ...

      template <typename Iter>
      mmappable_vector(Iter first, Iter last, A a = A()) : Base(begin, end, a) {}

};

See http://www.sgi.com/tech/stl/stl_vector.h


But the more important is that you should not define your vector like this at all:

template <typename T, typename A = mmap_allocator<T> >
    class mmappable_vector: public std::vector<T, A> {
            ...
    };

It is wrong because it derives from STL container, derivation is public and you do not have virtual destructor.


As far as I understand your question - you just need a typedef. There are two ways to make typedef in C++ - C++11 and C++03 ways:

C++11

template< typename T, typename A = mmap_allocator<T> >
using mmappable_vector = std::vector<T, A>;

C++03

    template <typename T, typename A = mmap_allocator<T> >
    struct mmappable_vector {
        typedef std::vector<T, A> type;
    };

Use it as:

    mmappable_vector<int>::type

Upvotes: 2

Related Questions