Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
实现Matlab';s冒号:C+中的运算符+;表达式模板类 我正在实现一个C++表达式模板库。我已经设置了一个适当的子矩阵xpr类来收集矩阵中的元素,启用了如下语法 B = SubMatrix(A,1,3,2,10);_C++_Expression_Metaprogramming - Fatal编程技术网

实现Matlab';s冒号:C+中的运算符+;表达式模板类 我正在实现一个C++表达式模板库。我已经设置了一个适当的子矩阵xpr类来收集矩阵中的元素,启用了如下语法 B = SubMatrix(A,1,3,2,10);

实现Matlab';s冒号:C+中的运算符+;表达式模板类 我正在实现一个C++表达式模板库。我已经设置了一个适当的子矩阵xpr类来收集矩阵中的元素,启用了如下语法 B = SubMatrix(A,1,3,2,10);,c++,expression,metaprogramming,C++,Expression,Metaprogramming,这相当于Matlab的 B = A(1:3,2:10); 当然,Matlab的语法比我的更容易理解。所以我的问题是 在C++中,是否有可能设置Matlab的冒号< >:< /C> >运算符? 事先非常感谢 简短回答:不。 冒号不是有效的C++运算符,因此不能重载。如果可以的话,仍然不可能轻松实现所需的功能,因为它肯定会优先于逗号运算符,这将使表达式位于A((1:3),(2:10))行中,并且仅当其中一个操作数是用户定义的类型时,才允许重载运算符(这里的情况并非如此) 因此,即使有其他操作员,您

这相当于Matlab的

B = A(1:3,2:10);
当然,Matlab的语法比我的更容易理解。所以我的问题是

在C++中,是否有可能设置Matlab的冒号< >:< /C> >运算符? 事先非常感谢

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

因此,即使有其他操作员,您也无法执行任何类似的操作

您可以做的是:为您的矩阵类重载
运算符()
,以获得合理的参数。如果您定义
运算符()(int,int,int,int);
,则可以编写类似
B=A(1,3,2,10);

我的首选解决方案是使用
操作符()
在C++11中使用两个
初始值设定项\u list
s或两个
std::array
。前者必须检查列表是否正好包含两个元素,后者需要一个笨拙的双括号进行初始化,这可能在C++14或更高版本中消失(N3526,但恐怕它不在C++14的CD中)。第三种可能性当然是可以调用的命名类,表示一个范围:

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
}
类矩阵{
/* ... */
公众:
矩阵运算符()(std::initializer\u list range1,std::initializer\u list range2);
//或:
矩阵运算符()(std::数组范围1,std::数组范围2);
//或:
矩阵运算符()(范围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));//更详细,但也更容易理解
}

另一个想法是在构造函数中设置参数的类型
char*
,然后在构造函数内部解析出
中的数字

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

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

这允许你做更多的事情,比如使用<代码>结束>代码> .< /p>不。C++中没有冒号操作符。但是,你可以重载其他操作符来做它。你将无法获得Matlab中的精确语法,但是你可以通过重载<代码>操作器来接近。

矩阵
类的,这样它就可以使用两个范围作为操作数。然后,您就可以编写
B=A(范围(1,3),范围(2,10))
,这可能比
子矩阵
版本更具可读性。@LucTouraille对
范围()
部分,我现在把它写进我的答案中。谢谢。@Luctureaille谢谢。你关于实现
Range
的建议对我来说非常有效。谢谢。Luc Toureille关于
Range
的建议对我来说非常有效。但是它效率很低,因为你需要解析字符串,
char*
对字符串来说是个坏主意,因为你不知道你手前的长度