在C ++表达式模板类中实现Matlab冒号:运算符

时间:2013-05-02 13:25:00

标签: c++ expression metaprogramming

我正在实现一个C ++表达式模板库。我已经设置了一个合适的SubMatrixExpr类来收集矩阵中的元素,启用类似

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

相当于Matlab的

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

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

是否有可能在C ++中设置Matlab的冒号:运算符?

非常感谢您提前。

2 个答案:

答案 0 :(得分:4)

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

因此,即使有其他任何操作员,您也无法做任何看起来像这样的事情。

可以做什么:为您的矩阵类重载operator(),以获得合理的参数。如果您定义B = A(1,3,2,10);

,这可以让您编写类似operator()(int,int, int, int);的内容

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

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
}

答案 1 :(得分:1)

另一个想法是在构造函数char *中创建参数的类型,然后在构造函数内部解析:中的数字。例如,

A = B("3:4","8:end");

A = B(":","2");

这允许您执行更多操作,例如使用end关键字。