在循环中对同一参数使用 std::forward

问题描述 投票:0回答:1

我知道在某些情况下,在循环中对同一参数使用 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
吗?

我尝试查看不同的堆栈溢出问题,但似乎没有一个具有我正在寻找的内容!

c++ c++11 c++20 rvalue-reference perfect-forwarding
1个回答
0
投票

根据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++ 代码,并且都涉及调用复制赋值运算符,因为函数参数不能被复制删除。

© www.soinside.com 2019 - 2024. All rights reserved.