在C ++表达式模板类中实现Matlab的冒号:运算符 [英] Implementing Matlab's colon : operator in C++ expression templates class

查看:266
本文介绍了在C ++表达式模板类中实现Matlab的冒号:运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现一个C ++表达式模板库。我已经设置了一个正确的 SubMatrixExpr 类来收集矩阵中的元素,从而支持如

  B = SubMatrix(A,1,3,2,10); 

这相当于Matlab的

  B = A(1:3,2:10); 

当然,Matlab的语法比我的更舒适。所以我的问题是



是否有可能在C ++中设置Matlab的冒号 / em>



提前非常感谢你。

解决方案

简答:否。
冒号不是一个有效的C ++运算符,所以不能重载。如果可以的话,仍然不可能轻松实现你所需要的,因为它最可能优先于逗号运算符,这将使您的表达式符合 A((1 :3),(2:10)),如果其中一个操作数是用户定义的类型(这不是这种情况),则只允许重载操作符。



所以即使有任何其他操作符,你也不能做任何类似的操作。



你可以对于您的矩阵类,请执行以下操作:重载 operator()。如果您定义了一个 operator()(int),这可以使您能够写出像 B = A(1,3,2,10); ,int,int,int);



我的首选解决方案将是一个 operator()采用C ++ 11或两个 std :: array< int,2> 中的两个 initializer_list 。前者必须检查列表是否包含两个元素,后者将需要一个尴尬的双重括号进行初始化 - 这可能会消失在C ++ 14或更高版本(N3526,但是它不在CD中的C ++ 14 )。第三种可能性当然是一个你可以调用的命名类,提供一个范围:

  class Matrix {
/ * ... * /
public:
矩阵运算符()(std :: initializer_list< int> range1,std :: initializer_list< int> range2);
//或
矩阵运算符()(std :: array< int,2> range1,std :: array< int,2> range2);
//或:
矩阵运算符()(范围范围1,范围范围2);

};

int main(){
矩阵A;
/ * ... * /
矩阵B = A({1,3},{2,10}); //注意A({1,3,2,4,5},{0})!
//或:
矩阵B = A({{1,3}},{{2,10}}); // uhgs ...
//或:
矩阵B = A(范围(1,3),范围(2,10)); //更冗长,但也更容易理解
}


I'm implementing a C++ expression templates library. I have set up a proper SubMatrixExpr class to collect elements within a matrix, enabling a syntax like

B = SubMatrix(A,1,3,2,10);

which is equivalent to Matlab's

B = A(1:3,2:10);

Of course, Matlab's syntax is much more confortable than mine. So my question is

Is there any possibility to set up Matlab's colon : operator in C++?

Thank you very much in advance.

解决方案

Short answer: no. The colon is not a valid C++ operator, so it cannot be overloaded. And if it could, it still would not be possible to achiev what you need easily, because it most surely would have precedence over the comma operator, which would make your expression be in the lines of A((1:3),(2:10)), and you are only allowed to overload operators if one of the operands is a user defined type (which is not the case here).

So even with any other operator in place, you could not do anything that looks like this.

What you can do: overload operator() for your matrix class, for sensible arguments. This could enable you to write something like B = A(1,3,2,10);, if you define an operator()(int,int, int, int);

My preferred solution would be an operator() taking either two initializer_lists in C++11 or two std::array<int,2>. The former would have to check that the list contains exactly two elements, the latter would need an awkward double brace for initialization - that might disappear in C++14 or later (N3526, but afaik it's not in the CD for C++14). Third possibility would of course be a named class that you could call, presenting a range:

class Matrix {
  /* ... */
public:
  Matrix operator()(std::initializer_list<int> range1, std::initializer_list<int> range2);
  //or:
  Matrix operator()(std::array<int,2> range1, std::array<int,2> range2);
  //or:
  Matrix operator()(Range range1, Range range2);

};

int main() {
  Matrix A;
  /* ... */
  Matrix B = A({1,3}, {2,10}); //beware of A({1,3,2,4,5}, {0}) !
  //or:
  Matrix B = A({{1,3}}, {{2,10}}); //uhgs...
  //or:
  Matrix B = A(Range(1,3), Range(2,10)); //more verbose, but also more understandable
}

这篇关于在C ++表达式模板类中实现Matlab的冒号:运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆