有没有合法的方法从gsl :: not_null <t>转移?

时间:2016-02-15 23:01:02

标签: c++ cpp-core-guidelines guideline-support-library

Guidelines Support Library引入not_null<T>的目的是强制执行类似指针的类型的不变量,通常在智能指针上。但是not_null<unique_ptr<T>> unique_ptr<T>不起作用。

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

我认为我们可以合法地从特定上下文中的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)); } 移动。

not_null<unique_ptr<int>>
  1. 我的假设是否正确,从f()返回的not_null<unique_ptr<int>>的状态在移动之后无法泄漏(仅用于示例)?

  2. 我的假设是否正确,传递给g()的public class EvenTest{ int getFirstEvenIndex(int[] array){ for (int r=0; r < array.length; r++){ if (array[r] % 2 ==0){ return r; } } return -1; } public static void main(String... args){ int[] arr = [3,5,1,2,7,8]; EvenTest et = new EvenTest(); System.out.println("First even is at index: " + et.getFirstEvenIndex(arr)); } } 状态在移动后无法泄漏(仅用于示例)?

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

1 个答案:

答案 0 :(得分:0)

1&amp; 2:忽略elision会使任何编译器值得使用的问题没有成功的事实,是的。同时忽略了unique_ptr 无法“泄露”的事实。

3:不。

这是关于ISO C ++提案邮件列表的一些争论的主题。一般概念是“破坏性移动”,其中从对象移动并销毁它的行为在同一个调用中执行。但这必须是语言功能;在C ++ 14中无法判断是否正在调用移动构造函数/赋值,以致于给定对象肯定会被销毁。