【发布时间】:2015-07-03 10:41:24
【问题描述】:
我一直在研究右值引用(对我来说是一个新概念),并且对我在以下类函数中收到的警告感到困惑......
string&& Sampler::Serial() const {
stringstream ss;
.
. [assemble a string value using data members]
.
return ss.str();
}
这编译成功,但出现以下警告...
..\Metrics\Sampler.cpp:71:16: warning: returning reference to temporary [-Wreturn-local-addr]
return ss.str();
^
我完全清楚我正在返回一个临时的,这一点可以从我使用右值引用作为我的返回类型这一事实来证明。代码在执行时似乎运行良好,那么为什么要保证编译器警告呢?
similar questions 的标准答案似乎是复制返回值而不是使用引用,但是当我可以使用右值引用移动它时,为什么要复制潜在的大量临时数据呢?这不就是它被发明的原因吗?
【问题讨论】:
-
右值引用仍然是引用;临时没有神奇的生命周期延长,它在控制权返回给
Serial()的调用者之前被销毁,所以你返回的引用总是悬空的。 -
您返回的不是临时的;您正在返回对临时的引用。你也没有移动任何东西。
-
我不确定我是否看到了 Johanne 对链接问题的回答中未讨论的问题。如果您简单地返回
std::string和ss.str(),您就不是在“复制可能大量”的任何东西。是什么让您认为如果正确调用移动语义会以某种方式不适用? -
@Syndog 未定义的行为会产生令人讨厌的结果,通常会做你认为应该做的事情,直到它没有做。
-
@Syndog
std::string支持移动构造;您将从str()返回的右值移动到您的 res 中,然后从 that 移动到调用者的目标中。std::string针对允许移动分配和移动构造进行了优化。简而言之,如果您仅使用std::string和return ss.str();,您几乎将不得不跳过障碍来强制这个not 做您想做的事情。