c++ - 在 C++ 函数中就地处理参数

标签 c++ c++11 reference

我正在向一个由第三方库定义的类添加一个辅助函数。此函数就地修改对象。如果我把这个函数写成一个方法,它看起来像这样:

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/

相关文章:

c++ - 传递常量引用...它是否像最重要的常量一样工作?

c++ - async_wait 中的 asio high_resolution_timer 段错误

objective-c - 保留和复制之间的区别?

php - 来自另一个函数的数组中的引用检测

c++ - << 和 >> 在 C++ 中

c++ - 免费 C++11 IDE 的建议

c++ - 将 boost::signals2::trackable 与 lambda 一起使用

c++ - 在 C++ 中将变量参数列表序列化为字节数组的最佳方法?

c++ - Android NDK链接V8静态库: cannot find symbols,但它们在那里

c++ - 类递归数组