1

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,

  • Johannes
1
  • 1
    look up the vector constructor that takes a pair of iterators. It doesn't take vector::iterators, it takes any iterators. Commented Oct 17, 2012 at 14:40

1 Answer 1

2

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 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your answer. As far as I understand it, I need the std::vector subclass because I have to add a method (mmap_file()) which modifies protected attributes of the std::vector class. What I am doing in this method is to set the size of the vector without initializing the content. The content for the mmappable_vector comes directly from the mmapped file, as far as I know there is no other way to achieve this. As for the destructor I do not have anything to destroy in the mmappable_vector class and use the destructor of std::vector (which calls deallocate on the allocator).
Please see github.com/johannesthoma/mmap_allocator for the complete source, I would highly appreciate if you can improve it. How do I write the constructor that takes iterators of any type (sorry for the silly question..). Constructor for std::vector::iterator cannot be overloaded and for the mmappable_vector it doesn't help because the iterators in to_mmappable_vector() are of type std::vector::iterator.
@JohannesThoma See update. You just need template constructor.
Thank you so much, I would never have thought about having a template within a template .. it compiles and seems to work now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.