vector of vector of unique_ptr

How do I fill a std::vector<std::vector<std::unique_ptr<Node>>> with blank vectors so that I can add to a specific level? I'm making a parse tree and I'm using a vector of unique_ptrs to manage ownership of each tier of nodes so I need a vector of vectors of unique_ptr and I can't do that because MinGW keeps coming up with errors such as no match for operator= in stl_vector.h.
Last edited on
How do I fill a std::vector<std::vector<std::unique_ptr<Node>>> with blank vectors
std::vector<std::vector<std::unique_ptr<Node>>> stuff {size}; creates a vector containing size vectors
What if I don't know size at compile time?
std::vector<std::vector<std::unique_ptr<Node>>> stuff {size}; creates a vector containing size vectors in runtime. size can be a variable
Let me rephrase. This vector of vectors is inside a class but it will not be used until later and size is not known until long after the constructor of the class in which the vectors are situated.
Thank you. It works. (Or at least I think it does. It's part of a really big project and I'll have no idea if it works without logic errors for a while but it does compile).
creates a vector containing size

Does it?
We are talking about:
std::vector<Foo> bar { size };

If it would call the fill constructor,
explicit vector (size_type n, const allocator_type& alloc = allocator_type());,
then the bar would indeed contain size default-constructed Foo objects.
(I shadowmouse's case, using Foo = vector<unique_ptr<Node>>;, size empty vectors.)

However, the std::vector has an another constructor too:
vector (initializer_list<value_type> il, const allocator_type& alloc = allocator_type());

The question is, will the
1
2
3
4
5
6
7
8
9
std::vector<Foo> bar { size };

// be interpreted as

std::vector<Foo> bar ( size ); // call fill ctor

// or as

std::vector<Foo> bar ( initializer_list<Foo>(size) ); // call initlist ctor 

IIRC, the brace syntax deviously prefers the initlist.

No matter, the parentheses syntax is valid.
There is no way an integral number will be converted to initializer_list<vector<unique_ptr<foo>>> as vector constructor taking single parameter is explicit.
I'll have no idea if it works without logic errors for a while

This is what unit tests are for :)
Last edited on
@MiiNiPaa: you are right, the explicit makes the difference. I had an inappropriate test case:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <vector>
#include <iostream>

struct Foo {
  Foo() = default;
  Foo( int ) {}
};

int main () {
 std::vector<Foo> foo ( 7 );
 std::vector<Foo> bar { 7 };
 std::vector<Foo> gaz ( 42, 7 );
 std::vector<Foo> qux { 42, 7 };
 std::cout << foo.size() << " vs " << bar.size() << " vs " << gaz.size()
   << " vs " << qux.size() << '\n';
 return 0;
}

7 vs 1 vs 42 vs 2



size is not known until long after the constructor

If the size is known right before adding elements, then the resize() or reserve()+emplace_back().
See http://www.cplusplus.com/reference/vector/vector/reserve/

If the size is known only after all the elements have been added, then plain emplace_back() -- unless you can make an educated guess for reserve().

The emplace_back() is usually more efficient than the older push_back(), but it depends on what objects you have to add.
Last edited on
Topic archived. No new replies allowed.