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;
}
};