如果可能的话移动插入的容器元素
我试图在我的容器库中实现以下优化:
- 插入左值引用元素时,将其复制到内部存储;
- 但是当插入右值引用元素时,移动它(如果支持)。
优化应该是有用的,例如,如果包含的元素类型类似于 std::vector ,如果可能的话移动将带来显着的加速。
然而,到目前为止我还无法为此制定任何工作方案。我的容器非常复杂,因此我不能多次重复 insert()
代码:它很大。我想将所有“真实”代码保留在一些内部助手中,例如 do_insert()
(可能是模板化的),并且各种类似 insert()
的函数只会调用它不同的论点。
我对此的最佳选择代码(当然,一个原型,没有做任何实际的事情):
#include <iostream>
#include <utility>
struct element
{
element () { };
element (element&&) { std::cerr << "moving\n"; }
};
struct container
{
void insert (const element& value)
{ do_insert (value); }
void insert (element&& value)
{ do_insert (std::move (value)); }
private:
template <typename Arg>
void do_insert (Arg arg)
{ element x (arg); }
};
int
main ()
{
{
// Shouldn't move.
container c;
element x;
c.insert (x);
}
{
// Should move.
container c;
c.insert (element ());
}
}
但是,这至少不适用于 GCC 4.4 和 4.5:它永远不会在 stderr 上打印“移动”。或者是我想要的不可能实现,这就是为什么像 emplace() 那样的函数首先存在的原因?
I'm trying to achieve the following optimization in my container library:
- when inserting an lvalue-referenced element, copy it to internal storage;
- but when inserting rvalue-referenced element, move it if supported.
The optimization is supposed to be useful e.g. if contained element type is something like std::vector
, where moving if possible would give substantial speedup.
However, so far I was unable to devise any working scheme for this. My container is quite complicated, so I can't just duplicate insert()
code several times: it is large. I want to keep all "real" code in some inner helper, say do_insert()
(may be templated) and various insert()
-like functions would just call that with different arguments.
My best bet code for this (a prototype, of course, without doing anything real):
#include <iostream>
#include <utility>
struct element
{
element () { };
element (element&&) { std::cerr << "moving\n"; }
};
struct container
{
void insert (const element& value)
{ do_insert (value); }
void insert (element&& value)
{ do_insert (std::move (value)); }
private:
template <typename Arg>
void do_insert (Arg arg)
{ element x (arg); }
};
int
main ()
{
{
// Shouldn't move.
container c;
element x;
c.insert (x);
}
{
// Should move.
container c;
c.insert (element ());
}
}
However, this doesn't work at least with GCC 4.4 and 4.5: it never prints "moving" on stderr. Or is what I want impossible to achieve and that's why emplace()
-like functions exist in the first place?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为您可能需要转发该参数:
完整代码:
您可能寻找的关键字是“完美转发”。
I think you may need to forward the argument:
Full code:
The keyword that you might look for is "perfect forwarding".
我建议复制它在 STL 实现(或 GNU,无论如何应该能够在线阅读)中完成的方式。
但
可能会成功。
此功能与
emplace
是分开的,并且您认为它在标准库中工作是正确的。编辑我做了一些更改并发现
move
但原始对象不为所动。因此,集中精力寻找正在移动的临时对象......这实际上并不是一件坏事。。
I'd recommend to copy the way it's done in your STL implementation (or GNU, which should be able to read online anyway).
But
might do the trick.
This functionality is separate from
emplace
and you're correct that it works in the standard library.EDIT I made some changes and discovered
move
but the original object was not moved. So focus on finding a temporary which is being moved… this isn't actually such a bad thing..
我不能说我明白为什么这个有效,而其他一些代码却不起作用,但这似乎可以解决问题(感谢 Potatoswatter 的提示而创建):
我在 GCC 4.4 和 4.5 中都得到以下输出:
I can't say I understand why this works and some other code doesn't, but this seems to do the trick (created thanks to hints from Potatoswatter):
I get the following output with both GCC 4.4 and 4.5: