Eigen库是在修改C++语法吗

Is the Eigen Library Modifying C++ Syntax

我最近一直在使用 Eigen,虽然一切都有意义,但我对这个库如何摆脱它使用的奇怪语法感到有点困惑。

比如定义一个矩阵,你应该做:

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;

或者您可以这样做:

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

虽然这些命令在概念上对我来说很有意义,但我很好奇它们对编译器有何意义。我以为<<是用来做位移的,括号是用来输入参数函数什么的,不是用来解析数组之类的矩阵结构的

我使用 C++ 的时间还不够长,无法理解所有这些语法,但我想知道 Eigen 的作者是否以某种方式定义了自定义语法或其他东西。

我不知道 Eigen,我认为你应该看看这些运算符是如何实现的。但是,一个小玩具示例可能有助于了解发生了什么。

#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);
}

重载 operator() 相当灵活,因为它允许任意数量的参数。返回对 data 元素的引用允许用户修改非常量 my_matrix 的元素。为了也允许访问 const my_matrix 的元素(而不修改它们),还有一个 const 运算符重载。与重载 operator() 类似,<< 也是一个可以重载以执行不同操作的运算符。有关运算符重载的更多信息,请参阅 here and here.

在这两个代码块中都有一些运算符重载。

在第一个代码块中,行 MatrixXd m(2,2); 创建对象 ,因为它是声明并且我们在那里有类型 MatrixXd。因此,m(i, j) 语法必须是调用接收两个参数的构造函数(也可以是接收更多参数的构造函数,只要其他参数有默认值即可)。

第一个代码块中的其他行没有调用构造函数,因此语法 m(i, j) 意味着调用 operator()(i, j) 的实现。从技术上讲,类似于 operator()(int i, int j)。 综上所述,第一个代码块只需要一个运算符重载,而且是人们经常实现的。

第二个代码块对我来说更像是魔法。 m << Number 部分表示 m 的类型 Matrix3f 具有 operator<< 的重载。然后我认为 operator<< returns1 的类型必须有逗号运算符的实现以允许 1, 2, 3, ... 部分。逗号运算符很少使用,它是重载恕我直言的最晦涩的运算符。总之,第二个代码块需要两个运算符重载,其中一个比较晦涩。是的,这很神奇。


1 它可能是对 m 的引用,因此是 Matrix3f 或者它甚至可能是由 Eigen 作者创建的完全不同的类型以允许这种初始化矩阵的好语法。