在下面的代码中,我有一个修改两个昂贵的复制对象的函数,我试图在没有输出参数的情况下离开
menu.add_cascade(label='Edit', menu=EditMenu)
我现在有点困惑,因为编译器不会发出任何警告,清理程序和memcheck都是干净的,并且代码可以工作。但!!!这不是用std :: tie创建的悬空引用吗?
答案 0 :(得分:1)
此处不会发生任何悬挂引用。 ft1
和ft2
是值,我们将它们绑定到引用,ft1
和ft2
(在块结束时到期)的生命周期超过引用(谁在该行的最后到期。)
然而:
auto ftings = processFatThings(move(ft1), move(ft2));
FatThing& ft1 = std::get<0>(ftings);
FatThing& ft2 = std::get<1>(ftings);
略微好一些,因为它移除了移动结构。它也符合
的要求 auto[ft1,ft2] = processFatThings(move(ft1), move(ft2));
在C ++ 17中做。
请注意,如果FatThing
在中有大数据成员,而不是拥有 ,move
无法帮助。 10亿个元素的数组需要10亿单位时间才能移动。同时,数据成员是10亿个元素的向量,移动比复制快得多。 (Vector拥有其缓冲区,它不会在其中存储缓冲区)
答案 1 :(得分:1)
不,没有悬挂的参考资料。 ft1
和ft2
将从processFatThings
请参阅以下代码,例如
#include <iostream>
#include <tuple>
#include <type_traits>
using std::cout;
using std::endl;
class Something {
public:
Something() {
cout << __PRETTY_FUNCTION__ << endl;
}
Something(Something&&) {
cout << __PRETTY_FUNCTION__ << endl;
}
Something(const Something&) {
cout << __PRETTY_FUNCTION__ << endl;
}
~Something() {
cout << __PRETTY_FUNCTION__ << endl;
}
Something& operator=(const Something&) {
cout << __PRETTY_FUNCTION__ << endl;
return *this;
}
};
int main() {
Something one, two;
std::tie(one, two) = std::make_tuple(Something(), Something());
}
现场演示https://wandbox.org/permlink/iG1qIJ2VKL4bljPM
在这里,您将看到有4个结构,对应于one
,two
和make_tuple
的两个参数。
然后两个移动make_tuple
的构造。
然后有两个副本分配。这是这里的关键部分。 Something
个对象被复制到与std::tie
“绑定”的任何对象。
所以没有悬空参考,你会得到副本/动作!