Search code examples
c++eigen

Is the Eigen Library Modifying C++ Syntax


I've been using Eigen recently and while everything makes sense, and I am just a little confused about how the library gets away with the weird syntax that it uses.

For example, when defining an matrix, you are supposed to do:

MatrixXd m(2,2); //defines a 3 x 4 matrix
m(0, 0) = 1;
m(0, 1) = 2;
m(1, 0) = 3;
m(1, 1) = 4;

or you can do something like:

Matrix3f m;
m << 1, 2, 3,
     4, 5, 6,
     7, 8, 9;
std::cout << m;

While these commands make sense conceptually to me, I am curious about how they make sense to the compiler. I thought << was used for bit-shifting and that the bracket notation was used for inputting parameter functions or something, not for parsing through a matrix structure like an array.

I haven't been working with C++ for long enough to understand all of this syntax, but I was wondering if the writers of Eigen somehow defined custom syntax or something.


Solution

  • In both code blocks there is some operator overloading.

    In the first code block, the line MatrixXd m(2,2); is creating the object, since it's the declaration and we have the type MatrixXd there. Therefore, the syntax m(i, j) must be a call to a constructor receiving two parameters (it can also be a constructor receiving more parameters as long as te other parameters have default values).

    The other lines in the first code block are not calling the constructor and therefore the syntax m(i, j) means calling the implementation of operator()(i, j). Technically, something similar to operator()(int i, int j). In summary, the first code block only needs one operator overload, and it is one people often implement.

    The second code block is what seems more like magic to me. The part m << Number means that the type of m, which is Matrix3f, has an overload for operator<<. Then I think that the type of whatever operator<< returns1 must have an implementation of the comma operator to allow the 1, 2, 3, ... part. The comma operator is rarely used and it is the most obscure operator to overload IMHO. In summary, the second code block requires two operator overloads and one of them is more obscure. Yeah, it's magic.


    1 It could be a reference to m and thus be Matrix3f or it could even be a completely different type created by Eigen authors to allow this nice syntax to initialize a matrix.