C++ “move from” container

北城以北 提交于 2019-12-04 16:03:06

问题


In C++11, we can get an efficiency boost by using std::move when we want to move (destructively copy) values into a container:

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

But I can't find anything going the other way. What I mean is something like this:

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

This is more frequent (the copy-pop) on adapter's like stack. Could something like this exist:

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

To avoid a copy? And does this already exist? I couldn't find anything like that in n3000.

I have a feeling I'm missing something painfully obvious (like the needlessness of it), so I am prepared for "ru dum". :3


回答1:


I might be total wrong here, but isn't what you want just

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

Assuming SomeExpensiveType has a move constructor. (and obviously true for your case)




回答2:


For completeness (and anyone stumbling on this question without a C++1x compiler), an alternative that already exists today:

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

It just requires a specialization of std::swap to exist for the element type.




回答3:


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
}



回答4:


Generally for expensive types I think you'd want to push either a wrapper class or smart pointer into the container instead. This way you are avoiding expensive copies and instead only doing the cheap copies of the smart pointer or the wrapper class. You can also use raw pointers too if you want haha.

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

   // copy constructors here....

private:
   ExpensiveWrapper* mPtr;

};


来源:https://stackoverflow.com/questions/2142965/c-move-from-container

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!