Here's a part of Eigen documentation:
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
Output:
1 2 3
4 5 6
7 8 9
I couldn't understand how could all the comma separated values be captured by operator<< above. I did a tiny experiment:
cout << "Just commas: ";
cout << 1, 2, 3, 4, 5;
cout << endl;
cout << "Commas in parentheses: ";
cout << ( 1, 2, 3, 4, 5 );
cout << endl;
Predictably (according to my understanding of C++ syntax) only one of the values was captured by operator<< :
Just commas: 1
Commas in parentheses: 5
Thus the title question.
The basic idea is to overload both the <<
and the ,
operators.
m << 1
is overloaded to put 1
into m
and then returns a special proxy object – call it p
– holding a reference to m
.
Then p, 2
is overloaded to put 2
into m
and return p
, so that p, 2, 3
will first put 2
into m
and then 3
.
A similar technique is used with Boost.Assign, though they use +=
rather than <<
.
This is a possible simplified implementation
struct M3f {
double m[3][3];
struct Loader {
M3f& m;
int i;
Loader(M3f& m, int i) : m(m), i(i) {}
Loader operator , (double x) {
m.m[i/3][i%3] = x;
return Loader(m, i+1);
}
};
Loader operator<<(double x) {
m[0][0] = x;
return Loader(*this, 1);
}
};
The idea is that <<
returns a Loader
instance that waits for second element, and each loader instance uses the comma operator to update the matrix and returns another loader instance.
Note that overloading the comma operator is generally considered a bad idea because the most specific characteristic of the operator is strict left-to-right evaluation order. However when overloaded this is not guaranteed and for example in
m << f(), g(), ...
g()
could end up being called before f()
.
Note that I'm talking about the evaluation order, not about associativity or precedence that are of course maintained also for overloaded versions.
For example g()
could be called before f()
but the result from f()
is guaranteed to be correctly placed in the matrix before the result from g()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With