如何在Eigen中使用逗号分隔初始化可能在C++中实现?

Mic*_*ael 9 c++ initialization operator-overloading eigen

这是Eigen文档的一部分:

Matrix3f m;
m << 1, 2, 3,
     4, 5, 6,
     7, 8, 9;
std::cout << m;
Run Code Online (Sandbox Code Playgroud)

输出:

1 2 3
4 5 6
7 8 9
Run Code Online (Sandbox Code Playgroud)

我无法理解如何通过operator <<上面捕获所有逗号分隔值.我做了一个小小的实验:

cout << "Just commas: ";
cout << 1, 2, 3, 4, 5;
cout << endl;
cout << "Commas in parentheses: ";
cout << ( 1, 2, 3, 4, 5 );
cout << endl;
Run Code Online (Sandbox Code Playgroud)

可以预测(根据我对C++语法的理解)只有一个值被operator <<捕获:

Just commas: 1
Commas in parentheses: 5
Run Code Online (Sandbox Code Playgroud)

因此标题问题.

T.C*_*.C. 17

基本思想是<<使,操作员和操作员都超载.

m << 1过载放1m,然后返回一个特殊的代理对象-称之为p-抱着一个参考m.

然后,p, 2过载放2m,并返回p,这样p, 2, 3会先将2进入m,然后3.

类似的技术与Boost.Assign一起使用,尽管它们使用+=而不是<<.


650*_*502 7

这是一种可能的简化实现

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

这个想法是<<返回一个Loader等待第二个元素的实例,每个加载器实例使用逗号运算符来更新矩阵并返回另一个加载器实例.

请注意,重载逗号运算符通常被认为是一个坏主意,因为运算符的最具体特征是严格的从左到右的评估顺序.但是当超载时,这不能保证,例如在

m << f(), g(), ...
Run Code Online (Sandbox Code Playgroud)

g()可能最终被召唤f().

请注意,我所说的是评估顺序,而不是关于当前为重载版本维护的关联性或优先级.例如g(),之前可以调用,f()但结果来自于结果之前f()保证正确放置在矩阵中g().