更新:
- 所以,根据让的评论,我已经查看了此链接。实际上,这与我要问的问题非常接近。唯一的区别是它明确处理类(毫无疑问是
cv::UMat
);但是,我要尝试使用返回类型的功能嵌套是否仍然有效?在预期的结果下,是否仍会发生复制责任?
问题
我目前正在使用OpenCV的cv::UMat
对象类,而我的同事写了一个函数来进行cv::UMat
添加,如下所示:
UMat addUMats(UMat & M1, UMat & M2){
UMat returnMat;
add(M1, M2, returnMat);
return move(returnMat);}
现在,如果我这样称呼为:
cv::UMat A = data1;
cv::UMat B = data2;
cv::UMat C = addUMats(A, B);
但是,当我尝试将函数作为参数传递给该函数时,我会得到一个"参数必须为lvalue"类型错误。例如,
cv::UMat A = addUMats(addUMats(alpha, beta), addUMats(alpha, beta));
对于任何有效的cv::UMats
,alpha, beta
。
到目前为止
我进行了一些研究,发现std::move(input)
明确返回了类型的rvalue。因此,出现错误是有道理的。
我意识到我可以首先做类似:
来解决此问题cv::UMat inputA = addUMats(alpha, beta);
cv::UMat A = addUMats(inputA, inputA);
,或者,我什至可以做类似的事情,
UMat addUMats(UMat & M1, UMat & M2){
UMat returnMat;
add(M1, M2, returnMat);
return returnMat;}
在哪种情况下,我理解该行return returnMat
会导致暂时复制的深(?)。
问题
所以,我知道这里可能有一些依赖性的事情。就像,也许是因为Umat类型有一些时髦的铸造或此类铸造。
但是,在一般情况下,适应函数的最佳方法
addUmats
能够作为调用该功能的函数?
我将在运行时寻求最有效的解决方案。另外,我不希望这个问题仅限于OPENCV案件;为使用std::move(input)
调用的任何类型的功能获得答案将不胜感激。
我认为您在函数的输入参数中缺少某些const
。尝试如下:
UMat addUMats(const UMat & M1, const UMat & M2) {
UMat returnMat;
add(M1, M2, returnMat);
return move(returnMat);
}
可能不是唯一的问题,但是就目前而言,您的函数不能将临时变量作为输入,因为它假定它们可以在函数内修改。
使用std::move
返回本地变量时,您禁止编译器执行RVO(返回值优化),这是因为您正在返回对UMAT的引用UMAT,标准需要返回相同类型的情况,如果允许编译器执行RVO。
如果编译器无论如何都选择不使用RVO,则必须将返回对象作为rvalue,因此当允许使用RVO时,使用copy Elision或STD ::移动被隐式应用。
>在这里:
cv::UMat A = addUMats(addUMats(alpha, beta), addUMats(alpha, beta));
问题在于addUMats
按值返回,addUMats
接受参考,但请参考。解决方案是添加rvalue版本的addumats:
UMat addUMats(UMat && M1, UMat && M2)
您的问题
您不能将RVALUE传递到您的功能中,因为该功能专门需要LVALUE(UMat&
)。
以这种方式考虑:addUMats
的参数可以在功能内更改。但是,当您进行addUMats(addUMats(alpha, beta), addUMats(alpha, beta));
时,您将在两个临时值上调用addUMats
,您以后将无法访问。
可能的解决方案
概念上,添加两个矩阵A和B不应更改A或B。因此,如果您确定您的同事不会在功能中更改A或B,则它们可以将功能的签名更改为:
UMat addUMats(const UMat & M1, const UMat & M2)
在这种情况下,问题解决了!您将能够在两个临时对象上调用addUMats
。由于它们无论如何都不会改变,所以没关系。
如果您需要优化的代码并利用Rvalue优化,则还可以将功能超载:
UMat addUMats(const UMat && M1, const UMat && M2)