我知道在某些情况下,在循环中对同一参数使用 std::forward 是错误的,因为它可能会导致从移动的对象中移动,如下所示:
template <typename T>
auto applyTenTimes(T&& arg, auto&& f){
for(int i = 0; i < 10; ++i)
f(std::forward<T>(arg);
return arg;
}
但是转发的对象再次被分配的情况怎么样,就像这个例子一样:
template <typename T>
auto applyTenTimes(T&& arg, auto&& f){
for(int i = 0; i < 10; ++i)
arg = f(std::forward<T>(arg);
return arg;
}
这有效吗?如果是,那为什么?它基本上从不创建一个新对象(当用右值调用时),只是将
arg
移动到函数 f
中,然后通过 RVO 再次移回 arg
吗?
我尝试查看不同的堆栈溢出问题,但似乎没有一个具有我正在寻找的内容!
根据std::forward的文档,这将根据输入是右值或左值进行扩展,如下所示。
// for moved lvalue
template <typename T>
auto applyTenTimes(T& arg, auto&& f){
for(int i = 0; i < 10; ++i)
arg = f(arg);
return arg;
}
// for rvalue
template <typename T>
auto applyTenTimes(T arg, auto&& f){
for(int i = 0; i < 10; ++i)
arg = f(std::move(arg));
return arg;
}
这两个函数都是完全有效的 C++ 代码,并且都涉及调用复制赋值运算符,因为函数参数不能被复制删除。