std :: list的一些方法,可能还有其他STL容器,在C ++ 11中添加了一个新的重载。我需要的是list :: splice()。一种方法需要一个列表&参数,另一个采取列表&&参数。
我想知道区别的是什么,以及我应该选择哪种方式。
我查看了libstdc ++(GCC编译器使用的标准C ++库)的实现,它使用了list&& amp;内部两种情况下的版本。此外,C ++ 11规范没有提到这个问题。它只提供了两种方法而没有解释它们之间的差异。
你不移动列表本身,并且你不移动节点(复制它们的指针似乎是将节点从一个列表移动到另一个列表的方式),那为什么重要呢?我只有一个想法,也许使用list&&就像对编译器的承诺,您不再需要其他列表,编译器可以保存一些操作,因为它不必保持其他列表有效...
答案 0 :(得分:5)
你不应该非常在意。当您传递的参数是右值时,将选择带有std::list&&
参数的重载 - 通常是当它引用的对象是临时对象时。您无需明确说明要使用的重载。
这两个版本的函数存在的原因是为了方便起见,因此客户端在将它传递给splice之前不必从临时对象创建临时std::list
变量(感谢@HowardHinnent注释)。
此外,当你拼接的列表是一个临时对象时,没有必要关心维持它的状态。函数的&&
版本可能只是从该列表中删除了内容,在整个楼层留下了一团糟。这可能是为了提高效率(但实际上,std::list
并没有太多理由)。
如果你有std::list
,other
,你知道你永远不会再使用,你可以自愿说“我不在乎你用它做什么”,使用{{ 1}}:
std::move
表达式l.splice(pos, std::move(other));
是一个右值,因此std::move(other)
函数会将其视为临时值。
答案 1 :(得分:3)
左值引用绑定到左值,右值引用右值:
tyedef std::list<Foo> lt;
lt make_list();
int main()
{
lt x;
lt tmp = make_list();
x.splice(tmp); // needs '&'
x.splice(make_list()); // needs '&&'
}