【问题标题】:How to check if a std::unique_ptr is null, if it is in a std::vector?如何检查 std::unique_ptr 是否为空,如果它在 std::vector 中?
【发布时间】:2020-11-09 13:43:21
【问题描述】:

我有一个 vector<unique_ptr<BaseClass>>,我正在通过调用 vec.push_back(std::make_unique<DerivedClass>()) 向其中添加新项目。

如何使用operator bool() 检查nullptr

我尝试直接使用vec.back(),像这样:

if((!vec.empty() && vec.back())
{
  // yay!
}
else
{
  //nay!
}

但无论指针的内容如何,​​它总是返回 false。

【问题讨论】:

  • 您能否尝试创建一个minimal reproducible example 向我们展示,我们可以尝试自己调试吗?谈到调试,您尝试过自己调试吗?
  • std::make_unique() 永远不会返回包含nullptrstd::unique_ptr。但是if (vec.back()) 将调用unique_ptr::operator bool 就好了,假设vec 不为空(否则调用back()未定义的行为)。所以无论你遇到什么问题都在你没有显示的代码中。
  • 谢谢!我会接受你的评论作为答案。我发现错误的代码很可能与这个问题无关。

标签: c++ pointers c++14 smart-pointers stdvector


【解决方案1】:

正如您从here 中看到的那样,如果向量为空,则它是 UB。如果不是您的情况,正如您从 here instead 中看到的那样,unique_ptr 有一个 operator bool(),它检查 对象当前是否由 unique_ptr 管理

所以,用:

vector.empty();

您可以检查向量是否有元素,并使用:

vector<unique_ptr<something>> vec;
vec.push_back(make_unique<something>());
if(vec.front()){ // example
    // do something
}

你检查第一个unique_ptr是否指向一个对象。

PS:如果你总是使用vec.push_back(std::make_unique&lt;DerivedClass&gt;()),你将永远不会有一个拥有nullptrunique_ptr

【讨论】:

  • 感谢您的确认,我也用建议扩展了问题。
【解决方案2】:

@Berto99 的回答提到了调用 std::vector::back 获取空的 std::vector 的问题(即 UB)。

另外,像@RemyLebeau提到的,如果你使用std::make_unique,它总是会返回the std::unique_ptr of an instance of type T(i.e. BaseClass)

我想在您的actual question 中添加一些内容。如果要检查有关最后插入的任何内容,可以使用 std::vector::emplace_back,它返回(C++17 起)对插入元素的引用。

std::vector<std::unique_ptr<BaseClass>> vec;
auto& lastEntry = vec.emplace_back(std::make_unique<BaseClass>());

if (lastEntry) // pointer check
{
    // do something with the last entry!
}

std::vector::push_back 相比,您的std::unique_ptr&lt;BaseClass&gt; 将就地构建。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-07
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    相关资源
    最近更新 更多