I wanted to make a Table class that is supposed to work like a table with columns and rows, and values in the cells. Obviously I need a function that would allow to get the value from a particular cell. I wanted this function (operator()
in my case) to return a reference, so that it would be easy to change the cell’s contents.
Now, I wanted to check in this function whether or not such a cell exists (i.e. are there enough columns and rows in the table). The problem is, I can’t just return something like a nullptr if col/row index is out of bounds in a function that returns a reference.
I’ve read some other topics on SO and people suggested using optional<reference_wrapper>
. Now, the problem is, I can’t assign anything to the returned value. Here’s the code:
class Table {
public:
class Column {
public:
std::string Header;
int Index = 0;
std::vector<std::string> colCells;
Column(std::string colHeader) { Header = colHeader; }
};
std::vector<Column> Columns;
std::optional<std::reference_wrapper<std::string>> operator()(int col, int row) {
return Columns[col].colCells[row];
}
void AddColumn(std::string colHeader) {
Column col(colHeader);
col.Index = Columns.size();
Columns.push_back(col);
for (auto& row : Columns[0].colCells) { //for each row in the first column (we created a column first, so there's at least this one)
col.colCells.push_back(""); //create a cell with an empty string
}
}
void AddRow() {
for (auto& col : Columns) {
col.colCells.push_back(""); //add empty string at the end of each column
}
}
};
AddColumn and AddRow methods aren’t important here, I guess, but I just pasted them here for the code to be complete.
Now, I tried this:
data::tbl(4, 0) = "Col: 2, Row: 0";
And that’s the errors I get. It seems as if this wasn’t an actual reference to the cell’s data. I should add that everything works fine the same way if I don’t use optional
and have the operator
What is happening and why?
PS. I know that another way to do all that, would be to change the return value to a pointer. But then I would have to dereference the returned pointer everywhere in the code like this:
*data::tbl(4, 0) = "Col: 2, Row: 0";
Which is something I’d rather avoid if possible.