传递堆栈对象的所有权而不重复

Passing ownership of stack object without duplication

第三方库有 API Huge computeHuge()。它 returns 对象本身,而不是 reference/pointer。我无法控制对象或 API.

我有两个 类:

class Bar {
  Huge h;
  Bar(Huge &huge): h(huge);
}

class Foo {
  Bar b;

  Foo() {
    Huge h = computeHuge();
    b = Bar(h);
  }

不幸的是,这种设计(暂时)导致了一个巨大对象的两个副本:一个副本存在于 Foo 构造函数中,另一个存在于 Bar 对象中。 Foo 构造函数退出后,只有一个副本,但我需要将构造函数内的内存加倍。由于 h 可能是数百 GB,这很重要。

此问题的一个解决方案是让 Foo 成为 h 的所有者:

class Bar {
  Huge &h;
  Bar(Huge &huge): h(huge);
}

class Foo {
  Bar b;
  Huge h;

  Foo() {
    h = computeHuge();
    b = Bar(h);
  }

这确实成功地消除了 h 的两个副本,但它在我的应用程序中并没有真正意义:Bar 是持有 h 的正确事物。 我怎样才能:

  1. Foo构造函数中调用computeHuge()
  2. Bar保留h
  3. 的所有权
  4. 所有 没有 内存中是否需要 h 的两个副本?

如果 Huge 是可移动的,则不会生成任何副本:

class Bar {
  Huge h;
  Bar(Huge huge): h(std::move(huge)) {}   // move huge into its final place, h
};

class Foo {
  Bar b;

  Foo() {
    Huge h = computeHuge();
    b = Bar(std::move(h));   // move h into constructor argument
    // h cannot be used here anymore
  }
};

出于调试目的,这是一个(微小的)Huge,不能复制,只能移动。每次尝试复制都是编译器错误:

struct Huge {
    Huge() = default;
    Huge(Huge&& other) { std::cout << "move "; }
    Huge(const Huge& other) = delete;
    Huge& operator=(Huge&& other) { std::cout << "move= "; return *this; }
    Huge& operator=(const Huge& other) = delete;
};