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

时间:2015-01-07 16:14:17

标签: c++ vector shared-ptr unique-ptr

我试图从我的vector中弹出我的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();

编译错误:

  

错误C2784:   &#39; enable_if ::值,标准::的unique_ptr&LT; _Ty,性病:: default_delete&LT; _Ty&GT;&GT;&GT; ::类型   std :: make_unique(_Types&amp;&amp; ...)&#39; :无法推断出模板参数   for&#39; _Types&amp;&amp;&#39;来自&#39; void&#39;

据我所知,我正在做我在别处看到的事情。

我看了make_unique info,但它没有给出一个非常好的例子,unique_ptr use。有什么想法吗?

4 个答案:

答案 0 :(得分:5)

您无法将所有权从共享指针转移到唯一指针。共享所有权后,它仍然是共享的。

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

答案 1 :(得分:4)

这里有很多错误:

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()返回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;

现在,这不会返回shared_ptr数据,而是返回它的副本。您无法将C ++ 11 shared_ptr的内容移动到unique_ptr。你可以用另一种方式做到这一点。

无论如何,你应该在你的矢量中存储unique_ptr

答案 2 :(得分:3)

std::vector::pop_back返回void。这就是你得到这个特定错误的原因,但是一旦你解决了这个问题,你就会遇到其他人提到的问题。

答案 3 :(得分:1)

我认为这样的事情会更好(假设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 ...不,你必须返回一个shared_ptr或在容器中存储unique_ptr。