特征库是否修改C++语法



我最近一直在使用 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 的作者是否以某种方式定义了自定义语法或其他东西。

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

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

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

第二个代码块对我来说更像是魔术。部分m << Number意味着m的类型,即Matrix3f,对operator<<有重载。然后我认为任何返回1operator<<的类型都必须具有逗号运算符的实现才能允许1, 2, 3, ...部分。逗号运算符很少使用,它是恕我直言重载的最晦涩的运算符。总之,第二个代码块需要两个运算符重载,其中一个更模糊。是的,这是魔术。


1它可以是对m的引用,因此是Matrix3f的,甚至可以是由 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()类似,<<也是一个可以重载做不同事情的运算符。有关运算符重载的更多信息,请参阅此处和此处。

最新更新