4

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

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

相当于 Matlab 的

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

当然,Matlab 的语法比我的舒服多了。所以我的问题是

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

非常感谢您提前。

4

2 回答 2

4

简短的回答:没有。冒号不是有效的 C++ 运算符,因此不能重载。如果可以,它仍然无法轻松实现您所需要的,因为它肯定会优先于逗号运算符,这将使您的表达式A((1:3),(2:10))位于其中一个操作数是用户定义的类型(这里不是这种情况)。

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

可以做什么:为您的矩阵类重载operator(),以获得合理的参数。这可以让你编写类似的东西B = A(1,3,2,10);,如果你定义一个operator()(int,int, int, int);

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

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
}
于 2013-05-02T13:41:21.717 回答
1

另一个想法是在构造函数中制作参数的类型char *,然后在构造函数中解析出:. 例如,

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

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

这允许您做更多事情,例如使用end关键字。

于 2017-11-05T14:46:14.097 回答