如何 pop_back 从 vector 共享指针并转换为 unique_ptr

how to pop_back shared pointer from vector and convert to unique_ptr

我正在尝试从我的向量中 pop_back 我的 shared_pointer 并转换为 unique_ptr。不幸的是,它给出了一条奇怪的编译信息。

IFCCB.cpp:

std::unique_ptr<IFC> IFCCCB::getElementVectorIFC()
{
    return (std::unique_ptr<IFC>(make_unique<IFC>(m_shpVectorIFC.pop_back())));
}

IFCCB.h:

public:
unique_ptr<IFC> getElementVectorIFC();

编译错误:

error C2784: 'enable_if::value,std::unique_ptr<_Ty,std::default_delete<_Ty>>>::type std::make_unique(_Types &&...)' : could not deduce template argument for '_Types &&' from 'void'

据我所知,我正在做我在其他地方看到的事情。

我看了make_unique info but it doesn't give a very good example, and unique_ptr use。有什么想法吗?

您不能将所有权从共享指针转移到唯一指针。一旦共享所有权,它就会保持共享状态。

如果您不需要与容器共享所有权,则存储唯一指针,或者如果需要,在从容器中移除后继续使用共享指针。

我认为这样的东西会更好(假设 m_shpVectorIFC 包含 unique_ptr 个对象):

std::unique_ptr<IFC> IFCCCB::getElementVectorIFC()
{
  auto result = std::move(m_shpVectorIFC.back());
  m_shpVectorIFC.pop_back();
  return result;
}

编辑:啊,刚看到里面的 shared_ptr 这个词...不,你必须 return 一个 shared_ptr 或在容器中存储一个 unique_ptr .

std::vector::pop_backreturnsvoid。这就是您遇到特定错误的原因,但是一旦您修复了该错误,您就会遇到其他人提到的问题。

这里有很多错误:

return (std::unique_ptr<IFC>(make_unique<IFC>(m_shpVectorIFC.pop_back())));

让我们把它分成多行,C++11 风格。这不是完全等同,但接近:

auto&& a = m_shpVectorIFC.pop_back();
auto&& b = make_unique<IFC>(std::move(a));
auto&& c = std::unique_ptr<IFC>(std::move(b));
return std::move(c);

这是一个不错的开始技巧。

现在您将收到一个包含更多信息的错误。

第一个问题是pop_back() returns void。解决这个问题:

auto a = std::move(m_shpVectorIFC.back()); // note a value, as we are about to mutate the vector
m_shpVectorIFC.pop_back();
auto&& b = make_unique<IFC>(std::move(a));
auto&& c = std::unique_ptr<IFC>(std::move(b));
return std::move(c);

我们仍然 运行 遇到问题。 IFC 不能从 std::shared_ptr<IFC>&& 构造。这不可以。我们可以复制一份:

auto a = std::move(m_shpVectorIFC.back());
m_shpVectorIFC.pop_back();
auto&& b = make_unique<IFC>(*a);
auto&& c = std::unique_ptr<IFC>(std::move(b));
return std::move(c);

接下来,auto&&c没有意义。

auto a = std::move(m_shpVectorIFC.back());
m_shpVectorIFC.pop_back();
auto&& b = make_unique<IFC>(*a);
return std::move(b);

我们不妨将 b 存储为一个值:

auto a = std::move(m_shpVectorIFC.back());
m_shpVectorIFC.pop_back();
auto b = make_unique<IFC>(*a);
return b;

然后一些错误检测:

auto a = std::move(m_shpVectorIFC.back());
m_shpVectorIFC.pop_back();
if (!a)
  return {};
auto b = make_unique<IFC>(*a);
return b;

和微优化:

auto a = std::move(m_shpVectorIFC.back());
m_shpVectorIFC.pop_back();
if (!a)
  return {};
auto b = a.unique()?make_unique<IFC>(std::move(*a)):make_unique<IFC>(*a);
return b;

现在,这不是 return shared_ptr 数据,而是它的副本。您不能将 C++11 shared_ptr 的内容移动到 unique_ptr 中。你可以换个方式。

很可能你应该在你的向量中存储一个 unique_ptr