C++ 唯一的\u ptr和默认可构造指针

C++ 唯一的\u ptr和默认可构造指针,c++,c++11,lambda,c++14,unique-ptr,C++,C++11,Lambda,C++14,Unique Ptr,最近,我试图通过std::unique\u ptr重新创建scope guard(注意:Deleter有成员typedef指针-是std::unique\u ptr的一个特殊处理案例): 唯一\u ptr仍然是指针。你不能把羔羊塞进里面。来自[unique.ptr]: 唯一指针是拥有另一个对象并通过指针管理另一个对象的对象。 更准确地说,唯一指针是一个对象u,它存储指向第二个对象p的指针,并将其丢弃 当u本身被破坏时 [……] 此外,u可以根据请求将所有权转移到另一个唯一指针u2。完成 在这种传

最近,我试图通过
std::unique\u ptr
重新创建scope guard(注意:Deleter有成员typedef
指针
-是
std::unique\u ptr
的一个特殊处理案例):


唯一\u ptr
仍然是指针。你不能把羔羊塞进里面。来自[unique.ptr]:

唯一指针是拥有另一个对象并通过指针管理另一个对象的对象。 更准确地说,唯一指针是一个对象u,它存储指向第二个对象p的指针,并将其丢弃 当u本身被破坏时

[……]

此外,u可以根据请求将所有权转移到另一个唯一指针u2。完成 在这种传输中,以下post条件保持不变:[…]u.p等于
nullptr

lambda不是指针。lambda不能等于
nullptr

也就是说,您已经在创建自己的本地结构,为什么不直接使用它来保护RAII范围本身,而不是遵从
unique\u ptr
?这充其量只是一种黑客行为,需要启动更多的代码。你可以只做:

template< typename lambda >
auto
make_scope_guard(lambda && _lambda)
{
    struct lambda_caller
    {
        lambda _lambda;

        ~lambda_caller()
        {
            _lambda();
        }

    };

    return lambda_caller{std::forward<lambda>(_lambda)};
}

std::unique_ptr
允许执行
release
以在范围结束前取消回滚
std::unique_ptr
-准备好使用具有所需语义的类。@除非它确实没有所需语义,否则它不会。对于这个用例,您真的需要
release()
?您也可以将它添加到我的
lambda_调用者中
,用
boost::optional
或类似的东西包装它。真的,我没有。但据我所知,这个成语需要
release()
。至少要尽可能灵活。@Orient足够容易添加。更新的答案。附加文本与提到的用例不相关(当删除器具有指针成员typedef时)。
struct D { void operator () () const noexcept { std::cout << __PRETTY_FUNCTION__ << std::endl; } /* constexpr operator bool () const { return true; } */ };
template< typename lambda >
auto
make_scope_guard(lambda && _lambda)
{
    struct lambda_caller
    {
        lambda _lambda;

        ~lambda_caller()
        {
            _lambda();
        }

    };

    return lambda_caller{std::forward<lambda>(_lambda)};
}
struct lambda_caller
{
    boost::optional<lambda> _lambda;

    ~lambda_caller()
    {
        if (_lambda) {
            (*_lambda)();
            _lambda = boost::none;
        }
    }

    void release() {
        _lambda = boost::none;
    }
};