如何检查std::vector中的std::unique_ptr是否为空?

3

我有一个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,无论指针的内容如何。


3
请您创建一个 [mcve] (最小可复现示例)以供我们查看和自行调试。关于调试,您已经尝试过自己调试了吗? - Some programmer dude
6
std::make_unique()永远不会返回持有nullptrstd::unique_ptr。但是,如果vec不为空(否则调用back()将导致未定义行为),则if(vec.back())可以很好地调用unique_ptr::operator bool。因此,您遇到的任何问题都在您未展示的代码中。 - Remy Lebeau
谢谢!虽然我会接受你的评论作为答案。但我发现有问题的代码很可能与这个问题无关。 - Dávid Tóth
2个回答

4

正如您可以从这里所阅读的那样,如果向量为空,则是未定义行为。如果不是这种情况,则正如您可以从这里所阅读的那样,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<DerivedClass>()),那么你永远不会有一个持有 nullptrunique_ptr


感谢确认,我还根据建议扩展了问题。 - Dávid Tóth

2

@Berto99的回答提到了调用空std::vectorUB问题,即调用std::vector::back

此外,像@RemyLebeau所说,如果使用std::make_unique,它将始终返回类型为T(即BaseClass)实例的std::unique_ptr

我想给你关于你的实际问题添加一些内容。如果你想检查最后一个插入的元素,可以使用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将会原地构造。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接