Range-v3运算符重载以编写较短的代码

时间:2019-02-15 17:36:48

标签: c++ c++17 range-v3

对于我的矩阵类,我想在+ - / * %的range-v3视图上进行某种类型的运算符重载(可能使用表达式模板)。 例如,如果要查看两列之和的视图,则要编写

col_1 + col_2

代替

rv::zip_with([](auto c1, auto c2) {return c1 + c2;}, col_1, col_2);

paper中的一些想法可能可以用来避免构造过多的临时对象。这是我要编写的代码:

//simple example
//what I want to write
auto rangeview =    col_1 + col_2;
//what I can write
auto rangeview =    rv::zip_with([](auto c1, auto c2) {
                        return c1 + c2;
                    }, col_1, col_2);


//itermediate
//what I want to write
auto rangeview =    col_1 + col_2 + col_3;
//what I can write
auto rangeview =    rv::zip_with([](auto c1, auto c2, auto c3) {
                        return c1 + c2 + c3;
                    }, col_1, col_2, col_3);


//advanced
//what I want to write
auto rangeview =    10*col_1 + 20*col_2 - 30*col_3;
//what I can write
auto rangeview =    rv::zip_with([](auto c1, auto c2, auto c3) {
                        return 10.0*c1 + 20.0*c2 - 30.0*c3;
                    }, col_1, col_2, col_3);


//more advanced with elementwise multiplication
//what I want to write
auto rangeview =    10*col_1 + 20*col_2 - col_2 % col_3;
//what I can write
auto rangeview =    rv::zip_with([](auto c1, auto c2, auto c3) {
                        return 10.0*c1 + 20.0*c2 - c2*c3;
                    }, col_1, col_2, col_3);

2 个答案:

答案 0 :(得分:0)

您主要担心的是可能会创建的(可能是巨大的)临时工。这可以通过称为表达式模板的概念来解决,但实际上并没有一种适合所有解决方案的尺寸。最好的选择可能是切换到支持该功能的矩阵库。除非您正在开发一个库或要对此进行投资,否则您可能希望避免编写自己的表达模板。一种更容易接近的方法,但是没有很多运算符重载/表达式模板,可以使用具有自定义迭代类型的基于范围的for循环(语法上不像表达式模板那样繁琐,但易于实现):

伪代码:

*resultype* result;//perhaps alloc on this line or make zip handle it..
for (auto z : zip(result, col_1, col_2, col_3)) {
  z[0] = 10.0*z[1] + 20.0*z[2] - 30.0*z[3];
}

这是在构思阶段,但比lambda样式要短一些(恕我直言,可读性更高)。 如何实现zip类,我不在这个答案之内。

答案 1 :(得分:0)

我同意@darune,除非您有强烈需求,否则应该使用库,尤其是Eigen。您要支持的大多数操作都显示在This link上。