开发者

C++ "move from" container

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),开发者_StackOverflow so I am prepared for "ru dum". :3


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)


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.


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
}


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;

};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜