I have a C class that has a datamember:
private:
std::vector<std::vector<int>> *edges;
Then in my constructor, I do the following:
//rows and columns are dynamically set in constructor
edges = new vector<vector<int> >(rows*columns, vector<int>());
edges[0].push_back(1);
When running my program, I get
error: no matching function for call to std::vector<std::vector<int> >::push_back(int)
edges[0].push_back(1);
^
I just know this has to do with pointers/references but I'm not experienced enough with C to figure it out and this error message feels so vague. Anybody know whats wrong here with these two lines?
EDIT1: I also tried changing the datamember to an object (not a pointer) and doing this but now my program is just stalling
for (int i = 0; i < (rows*columns); i ) {
vector<int> neighbors;
edges.push_back(neighbors);
}
EDIT2: I also tried using paxdiablo's answer but now this line is throwing a bad_alloc
edges = new vector<vector<int> >(rows*columns, vector<int>());
CodePudding user response:
Here's an example of loading a 2d vector:
std::vector<std::vector<int>> board;
for (int row = 0; row < 4; row)
{
std::vector<int> row;
for (int column = 0; column < 4; column)
{
row.push_back((row * 4) column);
}
board.push_back(row);
}
The above code initializes a 2d array, 4x4, with a unique number for each slot/square.
The inner loop initializes a "row" vector.
After the "row" vector is initialized, it is "push_back" to the "board" vector.
CodePudding user response:
edges is a pointer so edges[0] is actually the outer vector and you can't append an integer to a vector of vectors.
What you need is something like:
(*edges)[0].push_back(1);
The dereference gives you the outer vector, then the [0] gives you the first inner vector, which you can append an integer to.
There are other ways to do this, but the intent here is to simply explain what is happening.
Specifically, it's probably better to declare the vector in your class rather than a pointer to the vector. That way, you get it automagically during construction and you need not worry about allocating (or deallocating) it manually.
To do that, you simply use something like:
#include <iostream>
#include <iomanip>
#include <vector>
struct IntMatrix
{
IntMatrix(unsigned cols = 1U, unsigned rows = 1U)
{
// Disallow dimensions of size zero.
rows = std::max(1U, rows);
cols = std::max(1U, cols);
// Construct each column vector and add to row vector.
for (auto row = 0U; row < rows; row) {
std::vector<int> new_row;
for (auto col = 0U; col < cols; col) {
new_row.push_back(0);
}
m_matrix.push_back(new_row);
}
}
void set(unsigned col, unsigned row, int val) {
// Set value, silently ignore invalid indexes.
if (row < m_matrix.size() && col < m_matrix[0].size()) {
m_matrix[row][col] = val;
}
}
void print() {
// Print out each column for each row.
for (const auto &row: m_matrix) {
for (const auto &val: row) {
std::cout << std::setw(5) << val << ' ';
}
std::cout << '\n';
}
}
private:
// No need for destructor, vectors deallocate themselves.
std::vector<std::vector<int>> m_matrix;
};
// Test code, though a bit light on test cases :-)
int main() {
IntMatrix fourBySeven(4U, 7U);
fourBySeven.set(2U, 4U, 42);
fourBySeven.print();
}
The output of this, though bare bones, is what you would expect:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 42 0
0 0 0 0
0 0 0 0
