C++: Constructing a std::vector<std::vector<int> > with a two-dimensional C-array?
Solution 1
int map[18][25] = { /*...DATA GOES HERE...*/ };
std::vector<std::vector<int> > m;
m.reserve(18);
for (std::size_t i = 0; i != 18; ++i)
m.push_back(std::vector<int>(map[i], map[i] + 25));
In C++11, you can optionally replace the last line with the following to remove a little noise:
m.emplace_back(map[i], map[i] + 25);
Solution 2
Why do you want to do that? You have a contiguous block of memory and you are turning that into multiple blocks of memory. I would suggest that rather than that you provide a matrix
class that encapsulates the contents of a single std::vector<int>
of size 18*25
and provides accessors (operator()( int, int )
) for the elements that accesses col + row*columns
...
More in the C++ FAQ lite entry for operator overloading.
Comments
-
Casey almost 2 years
A std::vector can be constructed using a C-array like so:
std::vector<int> vec(ary, ary + len)
. What is the proper way to construct astd::vector<std::vector<int> >
?I've been brute-forcing the issue by manually copying each element into the vector, clearly this is not the intent, but it works.
int map[25][18] = { /*...DATA GOES HERE...*/ } std::vector<std::vector<int> > m(18, std::vector<int>(25, 0)); for(int y = 0; y < 18; ++y) { for(int x = 0; x < 25; ++x) { m[y][x] = map[y][x]; } }
-
HighCommander4 about 12 yearsIn addition to removing a little noise,
emplace_back()
is a little more efficient as well (since no moving has to be performed). -
ildjarn about 12 years+1 Agreed entirely, and here's a link to a proper existing, pre-tested matrix library: Boost.uBLAS.
-
Casey about 12 years-1. In addition to not answering the question you tried to tell me to create a class that's not even remotely related.
-
David Rodríguez - dribeas about 12 years@Casey: I am not sure you understood the suggestion. The answer I provided is that in most cases you don't want to do what you are asking for, but rather create a type (or use one like ildjarn points out) that encapsulates the matrix, and for which you can then decide how to implement. There is a clear advantage of using a sequential block of memory, and the fact that you have a type that encapsulates the operations allows you to do so. This class is closer binary-wise to the original array than a
std::vector<std::vector<int>>
because of the different layout. -
David Rodríguez - dribeas about 12 years@Casey: ... This includes the use with legacy components that might be expecting the former array, where you can obtain a bitwise compatible structure by casting the contents of the single vector into an array of the proper shape (I don't like casting, and I would rather refactor older interfaces, but the fact is that you can do it). Don't take me wrong, I don't care about the rep, if you don't like it downvote, but there is probably more value in the answer than what you seem to see in the first place.