下面是本征文档的一部分:
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
输出:
1 2 3
4 5 6
7 8 9
我不明白怎么会所有的逗号分隔值可以由运营商<<以上抓获。 我做了一个小实验:
cout << "Just commas: ";
cout << 1, 2, 3, 4, 5;
cout << endl;
cout << "Commas in parentheses: ";
cout << ( 1, 2, 3, 4, 5 );
cout << endl;
可以预见的是(根据我的C ++语法的理解)只中的一个值是由操作者<<捕获:
Just commas: 1
Commas in parentheses: 5
因此标题的问题。
其基本思想是超载两个<<
和,
运营商。
m << 1
是重载把1
到m
,然后返回一个特殊的代理对象-称之为p
-保持到参考m
。
然后p, 2
过载放2
到m
并返回p
,使得p, 2, 3
会先将2
到m
,然后3
。
类似的技术被用于与Boost.Assign ,虽然他们使用+=
而非<<
。
这是一个可能的简化实现
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);
}
};
这个想法是, <<
返回一个Loader
该等待第二元件实例,每个加载器实例使用逗号运算符来更新矩阵并返回另一个加载器实例。
需要注意的是重载逗号操作通常被认为是一个坏主意,因为运营商的最具体的特点是严格的左到右的计算顺序。 重载然而,当这不能保证,例如在
m << f(), g(), ...
g()
最终可能会之前被称为f()
请注意,我说的是评估顺序,不是那当然也保持了重载版本的关联性或优先级。 例如g()
之前可以被称作f()
,但是从结果f()
保证被正确地放置在基体中的结果之前,从g()
逗号本身位于c操作者++,其可以被重载(显然是通过本征)。 我不知道确切的方式征实现了重载,但我相信,你可以搜索的本征源来关注一下吧。
你的小experient你要了解未重载逗号操作符在C是如何工作++。
逗号运算符具有以下形式<statement>,<statement>
并进行评估,以任何第二个语句被评估以。 运营商<<
比运营商更高的优先级,
。 由于该cout
逗号操作的其余部分被评估之前进行评估。
因为,
被左到右结合的代码(1,2,3,4,5)
是等于((((1,2),3),4),5)
其计算结果为最合适的值,这是5
。
文章来源: How could comma separated initialization such as in Eigen be possibly implemented in C++?