【问题标题】:c++ return rvalue as const left refc++ 将右值作为 const left ref 返回
【发布时间】:2021-12-27 08:57:41
【问题描述】:

由于我们可以将右值传递给采用 const left ref 的函数,

void taking(const string& ref) {}

taking("abc");

我们可以在不报告警告的情况下将右值作为 const left ref 返回吗?

const string& returning()
{
    static string s = "abc";
    if (1)
    {
        return s;
    }
    else
    {
        return "xyz"; // warning: return-local-addr
    }
}

cout<<returning()<<endl;

【问题讨论】:

  • 这能回答你的问题吗? warning: returning reference to temporary
  • 嗨@Rana,我确实知道警告发生了什么。但我的情况是将右值的返回分支添加到返回 const left ref 的函数中。我认为这与您的问题有点不同。
  • 仔细查看我给出的链接问题。这个问题也有 if else 分支,就像你的一样。那里给出的答案已经解释了你在这里所拥有的。如果/当您在那里了解警告的原因时,您也可以在此处了解它,反之亦然。
  • 嗨@Rana,实际上在我的例子中,该函数是从一个接口派生的。所以它必须返回 const left ref 而不是 const 值。我可能会在函数中保留一个静态变量,在这种情况下会占用一些额外的内存

标签: c++ rvalue const-reference


【解决方案1】:

问题不在于值类别(左值与右值),而在于您根本返回引用这一事实。

什么类型的参考并不重要。当函数返回时,返回值所引用的对象将消失。在return s; 的情况下是局部变量,在return "xyz"; 的情况下它是在return 语句中构造的临时变量(必须构造,因为"xyz" 本身不是string,因此不能绑定到const string&amp;)。

您必须按值返回:

string returning()

如果你这样做了,那么returning() 形式的表达式将是一个纯右值(一种右值)并且可以用于例如在一个需要 const 左值引用的函数中,它也可以绑定到右值。

taking(returning()) // ok!

这没关系,因为函数本身的返回值在函数退出时并没有被破坏(那将是无意义的)。相反,它会一直持续到调用函数的完整表达式结束。

由于复制省略规则,也没有不必要的对象副本(return s; 中不太可能的额外移动操作除外)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2019-07-17
    • 2021-05-27
    • 2023-04-10
    相关资源
    最近更新 更多