4

Is there a standard container that has the same general API as vector<T> but that populates new locations via direct default construction?


Background:

I have a type that disallows copying but has a default constructor and what I really want to do is this:

vector<NoCopy> bag(some_size);

// use bag[i]'s

return; // bag & contents get correctly cleaned up. 

However, this doesn't work because vector<T>(int) is implemented in terms of default constructing an object and then copying it into each of the new locations.


Edit: Not C++0xB (a.k.a. C++11)

BCS
  • 75,627
  • 68
  • 187
  • 294

3 Answers3

5

One option would be to upgrade to a C++11-compliant Standard Library implementation.

In C++11, the vector(size_type) constructor default constructs N elements into the container. It neither copies nor moves any elements.

Visual C++ 2010 does not support this C++11 feature; I believe the Visual C++ 11 Developer Preview does correctly support it though. I do not know whether recent versions of libstdc++ support this; I would suspect that libc++ does.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • There is no `std::vector(size_type)` constructor. There is a `std::vector(size_type n, const T& value= T(), const Allocator& = Allocator())` constructor, which takes a value. It can be a default-constructed object or something you provide. Either way, it *copies* from this value `n` times. – Nicol Bolas Nov 30 '11 at 18:36
  • 5
    @NicolBolas: In C++98, yes. In C++11, there is a new constructor, `vector(size_type)`, which default constructs the elements directly into the container. An implementation is not permitted to copy or move any elements during the construction. – James McNellis Nov 30 '11 at 18:37
2

Boost.Container, new in Boost 1.48, has a boost::container::vector which provides this feature. It's C++03 conforming, with select C++11 features.

Well, there is one C++03 that boost::container::vector doesn't conform with: vector<bool> is actually a vector of bools. Though I imagine most people would count that as a benefit.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
2

Call it a workaround, but when I need containers of NoCopy types I usually use boost::ptr_vector or std::vector< shared_ptr >.

Obviously, it's slightly more expensive, but luckily for me that has not been a problem for me yet.

The good thing about boost::ptr_vector is that it does automatic dereferencing on some accesses. Check out the docs.

Martin Ba
  • 37,187
  • 33
  • 183
  • 337
  • Workaround for sure. The ugly with that is that I then have to go in and populate the thing. :( – BCS Nov 30 '11 at 21:14
  • @BCS - Yes, you are correct. Pre-populationg a noncopyable type into such a container can be annoying. – Martin Ba Dec 01 '11 at 06:06