Reputation: 178
Suppose I want to create a matrix class in C++ which can be initialised using the curly brackets:
matrix<int> M = {{1,2,3}, {2,3,1}}
As I found out, the right hand side is an std::initializer_list
object. I tried to implement the following:
template <typename ring>
class matrix {
private:
std::vector<std::vector<ring>> vals;
public:
matrix<ring>& operator=(const std::initializer_list<std::initializer_list<ring>>& rhs);
};
template<typename ring>
matrix<ring>& matrix<ring>::operator=(const std::initializer_list<std::initializer_list<ring>>& rhs) {
unsigned new_rows = rhs.size();
unsigned new_cols = 0;
for (unsigned i=0; i<new_rows; ++i) if (new_cols < rhs[i].size()) new_cols = rhs[i].size();
vals.resize(new_rows);
for (unsigned i=0; i<vals.size(); ++i) {
vals[i].resize(new_cols);
for (unsigned j=0; j<new_cols; ++j) {
vals[i][j] = rhs[i][j];
}
}
return *this;
}
This does not work, and I get keeping the error message that rhs cannot accept the rhs[i][j] implementation. What am I doing wrong?
Upvotes: 1
Views: 67
Reputation: 62684
matrix<double> M = {{1,2,3}, {2,3,1}}
Is copy-list-initialisation. You need a constructor
matrix<ring>(std::initializer_list<std::initializer_list<ring>> rhs) : vals(rhs.begin(), rhs.end()) {}
I'd retain the assignment operator, but implement it using the constructor
matrix<ring>& matrix<ring>::operator=(std::initializer_list<std::initializer_list<ring>> rhs) {
matrix temp = rhs;
std::swap(vals, temp.vals);
return *this;
}
Aside: std::initializer_list
is already a type with const reference semantics, you may as well take it by value.
Upvotes: 2