如果我正在构建一个不平凡的容器,例如自定义地图, 并且想要在
emplace
和 insert
函数之间共享代码,一种方法是让 insert
函数简单地调用 emplace
,并使用提供的元素作为参数。
例如:
template<typename... args>
iterator emplace(int id, args &&... params)
{
// Do complex stuff here, get a location
*location = value_type(std::forward<arguments>(parameters) ...);
}
iterator insert(int id, const value_type &element)
{
emplace(id, element);
}
如果我理解正确的话,在
insert &
的情况下应该简单地调用复制构造函数?
然而,在 insert &&
的情况下,它变得有点混乱:
iterator insert(int id, value_type &&element)
{
emplace(id, std::move(element));
}
std::move
将元素转换为 xvalue,这很好 - 但是 std::forward
会适当地处理这个问题吗? IE。对于具有非默认移动构造函数的非平凡 value_type
,上面的 emplace
构造行会正确调用移动构造函数吗?
如果我理解正确的话,在
的情况下应该简单地调用复制构造函数?insert &
是的,在这种情况下,您给
std::forward
一个 const 左值,并且 std::forward
产生一个 const 左值。
这样,复制构造函数就被调用了。
将元素转换为 xvalue,这很好 - 但std::move
会适当地处理这个问题吗?std::forward
是的。
std::forward
将右值转换为x值,将左值转换为左值。
只要你不给它一个左值,它就不会给你一个左值。
这随后意味着将按预期调用移动构造函数。
在
args &&... params
中,args
推导为 value_type
,在实例化函数模板时使 params
成为右值引用。
调用 std::forward
的 第二次重载,并且 std::forward<args>(params)
产生 x 值。
实际上,以
push_back
或 insert
的形式为容器实现 emplace_back
或 emplace
是很常见的。