我正在向一个由第三方库定义的类添加一个辅助函数。此函数就地修改对象。如果我把这个函数写成一个方法,它看起来像这样:
myObject &doTheThing( int someParameter ) {
myProperty = someParameter;
return *this;
}
所以它可以这样调用:
myInstance = instance1 + instance2;
myInstance.doTheThing( );
或
display( (instance1 + instance2).doTheThing( ) );
效果很好。但由于我无法扩展该对象,所以我将其编写为辅助函数;
myObject &doTheThing( myObject &object, int someParameter ) {
object.myProperty = someParameter;
return object;
}
这在第二个用例中无效,因为临时不能绑定(bind)到非常量引用(人为的测试用例:http://codepad.org/5frJjCUb)。有没有办法在不使用传递复制的情况下解决这个问题?如果复制是唯一的方法,是否有一些最佳实践方法可以帮助编译器正确优化它? (C++11 很好)
最佳答案
您可以使用 c++11 rvalue
解决它。
The purpose of r-value reference parameters is to detect specifically when an object is an r-value. Because if an object is an r-value, then the function knows it won't be used again, so it can do whatever it wants with it.
你可以重载这个函数:
myObject &doTheThing( myObject &object, int someParameter ) {
object.myProperty = someParameter;
return object;
}
myObject &doTheThing( myObject &&object, int someParameter ) {
// ^^
object.myProperty = someParameter;
return object;
}
保留你的实现,只添加带有 rvalue
的实现,因为当我一开始所说的检测没有发生时,你必须有一个函数采用 lvalue
引用。
例如:
doTheThing( instance1 + instance2, 1 ) // uses the rvalue implementation
doTheThing( myInstance, 1); // uses the lvalue implementation
编辑:
正如评论中所说,您可以跳过重载实现 但这会导致最后一个问题:使用 rvalue
引用似乎可以解决问题,但如果我们进一步观察: (instance1 + instance2)
创建的临时对象会在doTheThing
执行后销毁。解决方案可能是:
myObject &doTheThing( myObject &object, int someParameter ) {
object.myProperty = someParameter;
return object;
}
myObject doTheThing( myObject &&object, int someParameter ) {
// ^
object.myProperty = someParameter;
return object;
}
重载的按值返回会避免一些生命问题。
但是你现在不能跳过重载实现,因为编译器会产生这个错误:
error C2664: 'concat' : cannot convert parameter 1 from 'MyObj' to 'MyObj &&'
You cannot bind an lvalue to an rvalue reference
关于c++ - 在 C++ 函数中就地处理参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17787898/