在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
答案 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;
};