C++ 是否有合法的方式从gsl::not_null<;T>;?

C++ 是否有合法的方式从gsl::not_null<;T>;?,c++,cpp-core-guidelines,guideline-support-library,C++,Cpp Core Guidelines,Guideline Support Library,引入的not_nullwho的目的是在类似指针的类型上强制执行不变量,特别是在智能指针上。但是,not_null不起作用 据我所知,原因是unique\u ptr不可复制构造,而且not\u null没有从其t移动的构造函数。not\u null也不是默认可构造的,因为它会破坏它的不变量。即使我们可以构造not_null,也不可能有意义地到达内部的unique\u ptr,因为我们无法复制unique\u ptr,移动它将使not_null保留一个null ptr。它看起来像一个完美的陷阱 我认

引入的
not_null
who的目的是在类似指针的类型上强制执行不变量,特别是在智能指针上。但是,
not_null
不起作用

据我所知,原因是
unique\u ptr
不可复制构造,而且
not\u null
没有从其t移动的构造函数。
not\u null
也不是默认可构造的,因为它会破坏它的不变量。即使我们可以构造
not_null
,也不可能有意义地到达内部的
unique\u ptr
,因为我们无法复制
unique\u ptr
,移动它将使
not_null
保留一个null ptr。它看起来像一个完美的陷阱

我认为我们可以合法地从特定上下文中的
not_null
对象移动:就在它超出范围之前。换句话说,离开它应该是毁灭之前的最后一次进入。这样,程序的其余部分就看不到具有破碎不变量的对象。(只有
not_null
自己的代码才能看到它。)

在下面的示例中,我们假设可以从
not_null
移动

非空f()
{
返回使_唯一(1);
}
空g(非空p)
{
...
}
void h()
{
自动p=f();
g(使_唯一(2));
}
  • 我的假设是否正确,即从f()返回的
    not_null
    的状态在从其移动后不会泄漏(仅用于示例)

  • 我的假设是否正确,即传递给g()的
    not_null
    的状态在从g()移动后不会泄漏(仅用于示例)

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


  • 1和2:忽略省略会使问题在任何值得使用的编译器上变得毫无意义这一事实,是的。同时忽略
    unique\u ptr
    不能“泄漏”这一事实

    3:没有


    这是关于ISO C++提案邮寄列表的一些争论的主题。一般的概念是“破坏性移动”,即从一个物体移动并摧毁它的行为在同一个呼叫中执行。但这必须是一种语言特征;在C++14中,无法判断是否调用了移动构造函数/赋值,因此给定的对象肯定会被销毁。

    1&2:忽略省略会使问题在任何值得使用的编译器上变得毫无意义的事实,是的。同时忽略
    unique\u ptr
    不能“泄漏”这一事实

    3:没有


    这是关于ISO C++提案邮寄列表的一些争论的主题。一般的概念是“破坏性移动”,即从一个物体移动并摧毁它的行为在同一个呼叫中执行。但这必须是一种语言特征;在C++14中,无法判断是否调用了移动构造函数/赋值,因此给定的对象肯定会被销毁。

    复制省略非常棘手,因为它是“唯一允许的可以改变可观察到的副作用的优化形式”(来自cppreference.com)。谢谢你提到这件事。我说的泄露是指泄露信息而不是内存,但你的评论无论如何都是相关的。最后,我不知道这场辩论,但这是我所期待的。复制省略确实很棘手,因为它是“唯一允许的可以改变可观察到的副作用的优化形式”(来自cppreference.com)。谢谢你提到这件事。我说的泄露是指泄露信息而不是内存,但你的评论无论如何都是相关的。最后,我不知道这场辩论,但这是我所期待的。关于3:看,特别是来自hsutter的评论。对于一般解决方案,move构造与
    std::move
    结合是一个问题,请比较
    auto p=f();自动q=标准::移动(p)其中,移动后
    p
    无法保存任何不违反类不变量“not null”的有意义值(没有有效的默认值可设置
    p
    to)。关于3:请参阅,尤其是来自hsutter的注释。对于一般解决方案,move构造与
    std::move
    结合是一个问题,请比较
    auto p=f();自动q=标准::移动(p)其中,移动后
    p
    无法保存任何不违反类不变量“not null”的有意义的值(没有有效的默认值可设置
    p
    )。
    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));
    }