【问题标题】:Returning const reference parameter without copying返回 const 引用参数而不复制
【发布时间】:2021-08-13 09:46:03
【问题描述】:

我想返回一个重对象,我将其作为const 引用传递而不复制。代码如下所示:

#include <iostream>

class heavy_obj {
    public:
        heavy_obj() {
            std::cout << "Standard" << std::endl;
        }

        heavy_obj(const heavy_obj&) {
            std::cout << "Copy" << std::endl;
        }

        heavy_obj(heavy_obj&& t) {
            std::cout << "Move" << std::endl;
        }

};

heavy_obj return_obj_or_default(const heavy_obj& t, bool ret) {
    if(ret) {
        return std::move(t); // Copy gets called here
    } else {
        return heavy_obj();
    }
}

int main()
{
    heavy_obj t {/* Something */};
    heavy_obj t2 = return_obj_or_default(t, true);
    heavy_obj t3 = return_obj_or_default(heavy_obj(/* Something Else */), true);
    /* Output:
       Standard
       Copy
       Standard
       Copy
    */
    return 0;
}

但是,如果我将移动构造函数声明为非const,如上所示,将调用复制构造函数,这是我不想要的。我可以删除函数heavy_obj return_test(heavy_obj&amp; t, bool ret) 中的const,但我不能再将右值作为参数传递。

如何实现我想要的行为?将移动构造函数的参数标记为const:heavy_obj(const heavy_obj&amp;&amp; t)?虽然它与this 矛盾?

【问题讨论】:

  • 那我就不能再把右值作为参数传递了 把参数标记到移动构造函数,你为什么不用 return_obj_or_default(heavy_obj&& t,bool ret)
  • @HongluWong 因为我想将引用作为return_obj_or_default(t, true) 或右值return_obj_or_default(heavy_obj(), true) 传递,所以我无法通过heavy_obj&amp;&amp; t 传递引用
  • 你应该使用 std::forward,这样的代码 ` template typename std::decay::type return_obj_or_default(T&& t,bool ret ){ if( ret ) 返回 std::forward(t);返回类型名 std::decay::type{};`
  • 嗯,对于这样一个基本任务有很多黑客攻击,但至少它适用于move

标签: c++ move-semantics


【解决方案1】:

您无法从const 值移动,因此该函数无法通过const &amp;

您可以这样做,因此调用者必须提供一个右值,移动或显式复制他们希望传递的左值。

heavy_obj return_obj_or_default(heavy_obj&& t, bool ret) {
    if(ret) {
        return std::move(t);
    } else {
        return heavy_obj();
    }
}

或者你可以这样做,所以调用者不需要做任何特别的事情,但它会隐式复制左值。

heavy_obj return_obj_or_default(heavy_obj t, bool ret) {
    if(ret) {
        return std::move(t);
    } else {
        return heavy_obj();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 2020-07-17
    • 2013-06-08
    • 1970-01-01
    相关资源
    最近更新 更多