简体   繁体   中英

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.

I dont know Eigen and I think you should take a look at how these operators are implemented. However, a small toy example may help to see what is going on.

#include <array>
#include <iostream>

struct my_matrix {
    std::array< std::array< int,10>,10> data;
    int& operator()(size_t i,size_t j) { return data[i][j]; }
    const int& operator()(size_t i,size_t j) const { return data[i][j]; }
};


int main (){
    my_matrix x;
    x(1,1) = 42;
    std::cout << x(1,1);
}

Overloading operator() is rather flexible, because it allows aribtrary number of parameters. Returning a reference to an element of data allows the user to modify elements of a non-const my_matrix . To also allow accessing elements of a const my_matrix (without modifiying them) there is also a const overload of the operator. Similarly to overloading operator() , << is also an operator that can be overloaded to do different things. For more on operator overloading see here and here .

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<< returns 1 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM