C ++“从容器中移出”

时间:2010-01-26 21:59:24

标签: c++ c++11 containers rvalue-reference

在C ++ 11中,当我们想要将值移动(破坏性地复制)到容器中时,我们可以通过使用std::move来提高效率:

SomeExpensiveType x = /* ... */;
vec.push_back(std::move(x));

但我找不到任何其他方式。我的意思是这样的:

SomeExpensiveType x = vec.back(); // copy!
vec.pop_back(); // argh

这在stack等适配器上更常见(copy-pop)。可能存在这样的事情:

SomeExpensiveType x = vec.move_back(); // move and pop

避免复制?这已经存在了吗?我在n3000中找不到类似的东西。

我有一种感觉,我错过了一些非常明显的东西(比如它的不必要),所以我准备好了“ru dum”。 :3

4 个答案:

答案 0 :(得分:17)

我可能在这里完全错了,但不是你想要的只是

SomeExpensiveType x = std::move( vec.back() ); vec.pop_back();

假设SomeExpensiveType有一个移动构造函数。 (显然你的情况也是如此)

答案 1 :(得分:4)

为了完整性(任何人在没有C ++ 1x编译器的情况下绊倒这个问题),今天已经存在的替代方案:

SomeExpensiveType x;
std::swap(x, vec.back()); 
vec.pop_back();

只需要对元素类型存在std::swap的特化。

答案 2 :(得分:4)

template<class C>
auto pop_back(C& c) -> typename std::decay<decltype(c.back())>::type
{
  auto value (std::move(c.back()));
  c.pop_back();
  return value;  // also uses move semantics, implicitly
  // RVO still applies to reduce the two moves to one
}

答案 3 :(得分:-1)

通常对于昂贵的类型,我认为你想要将包装类或智能指针推入容器中。这样您就可以避免使用昂贵的副本,而只需执行智能指针或包装类的廉价副本。如果你想要haha,你也可以使用原始指针。

class ExpensiveWrapper
{
public:
   ExpensiveWrapper(ExpensiveClass* in) { mPtr = in; }

   // copy constructors here....

private:
   ExpensiveWrapper* mPtr;

};