std :: tie和元组中返回的对象的生命周期

时间:2017-07-11 13:51:14

标签: c++ c++11 tuples lifetime

在下面的代码中,我有一个修改两个昂贵的复制对象的函数,我试图在没有输出参数的情况下离开

menu.add_cascade(label='Edit', menu=EditMenu)

我现在有点困惑,因为编译器不会发出任何警告,清理程序和memcheck都是干净的,并且代码可以工作。但!!!这不是用std :: tie创建的悬空引用吗?

2 个答案:

答案 0 :(得分:1)

此处不会发生任何悬挂引用。 ft1ft2是值,我们将它们绑定到引用,ft1ft2(在块结束时到期)的生命周期超过引用(谁在该行的最后到期。)

然而:

  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)

不,没有悬挂的参考资料。 ft1ft2将从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个结构,对应于onetwomake_tuple的两个参数。

然后两个移动make_tuple的构造。

然后有两个副本分配。这是这里的关键部分。 Something个对象被复制到与std::tie“绑定”的任何对象。

所以没有悬空参考,你会得到副本/动作!