【问题标题】:Assign smart pointer in condition or loop在条件或循环中分配智能指针
【发布时间】:2017-10-18 22:32:20
【问题描述】:

我正在更新一些 c++11 之前的代码以使用 c++11 unique_ptrs。

我不确定如何处理的一件事是旧代码何时使用指针赋值作为条件。例如

Object* obj;
while ( obj = C_LIBRARY_CALL_WHICH_RETURNS_NEW_OBJECT() )
{
   // do something with obj
   delete obj;
}

鉴于 std::unique_ptr::reset 没有返回值,因此无法将其直接转换为:

std::unique_ptr< Object > obj;
while ( obj.reset( C_LIBRARY_CALL_WHICH_RETURNS_NEW_OBJECT() ) )
{
   // do something with obj
}

那么,升级此代码以使用 unique_ptrs 的最简洁方法是什么?我能想到的最好的是:

std::unique_ptr< Object > obj;
obj.reset(  C_LIBRARY_CALL_WHICH_RETURNS_NEW_OBJECT() );
while ( obj )
{
   // do something with obj
   obj.reset(  C_LIBRARY_CALL_WHICH_RETURNS_NEW_OBJECT() );
}

但这会给库函数添加混乱的双重调用,理想情况下我想避免这种情况。

【问题讨论】:

  • 如果你使用的是 C++17,它允许:while ( obj.reset( LIBRARY_CALL() ); obj )
  • @aschepler:现在怎么办?
  • C_LIBRARY_CALL_WHICH_RETURNS_NEW_OBJECT 你是哪个delete?这很可疑。
  • 可能我把这个例子简化得太多了——实际上,unique_ptr 是用一个自定义删除器定义的,它调用了库的清理函数。
  • @KerrekSB open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r1.html,2016 年 6 月接受。

标签: c++ c++11 unique-ptr


【解决方案1】:

怎么样:

while ( auto obj = std::unique_ptr<Object>( C_LIBRARY_CALL_WHICH_RETURNS_NEW_OBJECT() ) )
{
   // do something with obj
}

【讨论】:

  • while 检查unique_ptr 是否为空(通过其bool 转换运算符),因此无需检查循环体内的obj 是否为空
  • 你可以通过写while (std::unique_ptr&lt;Object&gt; obj{ LIBRARY_CALL_WHICH_RETURNS_NEW_OBJECT() })来丢失自动。请注意,它必须是 C++ 库调用,而不是 C 库,因为 C 分配器和 C++ new/delete 不兼容。
  • 答案方法的缺点是这限制了指针的范围,因此您不能break; 退出while循环并继续使用指针。
  • @BenVoigt,我喜欢auto 和左侧的定义。我真的很喜欢 Herb Sutter 在 CppCon 中提出的概念,他说类型定义正在向右移动。
  • 范围限制对我来说是一个加分项 - 原始实现将循环直到返回 nullptr,因此循环之外的任何使用无论如何都是无效的。
【解决方案2】:

如果你想让obj在循环外保持活跃,你可以使用逗号操作符:

std::unique_ptr< Object > obj;
while ( obj.reset(  C_LIBRARY_CALL_WHICH_RETURNS_NEW_OBJECT() ), obj )
{
    // do something with obj
}

【讨论】:

  • 我以前从未遇到过这种逗号的用法 - 但在这种情况下,这是一个非常优雅的解决方案!
猜你喜欢
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-10
  • 2017-05-06
相关资源
最近更新 更多