是否有合法的方式从 gsl::not_null<T> 移动?

Is there a legal way to move from gsl::not_null<T>?

not_null<unique_ptr<T>>Guidelines Support Library introduced not_null<T> who's purpose is to enforce an invariant on pointer-like types, advertently on smart pointers. However it's a known issue不行

据我所知,原因是 unique_ptr<T> 不是可复制构造的,并且 not_null<T> 没有可以从其 T 移动的构造函数。 not_null<T> 不是默认可构造的,因为它会破坏它的不变性。即使我们可以构造 not_null<unique_ptr<T>>,也不可能有意义地到达内部的 unique_ptr,因为我们无法复制 unique_ptr 并且移动它会留下带有 nullptr 的 not_null<T>。这看起来像一个完美的陷阱。

我认为我们可以在特定上下文中合法地从 not_null<T> 对象移动:就在它超出范围之前。换句话说,从中移动应该是销毁前的最后访问。这样,程序的其余部分将无法观察到不变量损坏的对象。 (只有 not_null 自己的代码才能观察到。)

在下面的例子中,我们假设我们可以从 not_null<T>.

not_null<unique_ptr<int>> f()
{
    return make_unique<int>(1);
}

void g(not_null<unique_ptr<int>> p)
{
    ...
}

void h()
{
    auto p = f();
    g(make_unique<int>(2));
}
  1. 我的假设是否正确,从 f() 返回的 not_null<unique_ptr<int>> 的状态在从它移动后不会泄漏(仅作为示例)?

  2. 我的假设是否正确,即传递给 g() 的 not_null<unique_ptr<int>> 的状态在从它移动后不会泄漏(仅作为示例)?

  3. 在 C++14/17 中是否可以允许这种特殊类型的移动,同时禁止常见的移动情况?

1&2:忽略省略会使问题在任何值得使用的编译器上都没有实际意义的事实,是的。也忽略了 unique_ptr 不能 "leak".

的事实

3:没有

这一直是 ISO C++ 提案邮件列表中一些争论的主题。一般概念是 "destructive move",其中从对象移动和销毁它的动作是在同一个调用中执行的。但这必须是一种语言特性;在 C++14 中没有办法判断是否正在调用移动 constructor/assignment 使得给定对象肯定要被销毁。