为什么右值参考传递为左值参考?

Jak*_*kob 5 c++

pass()引用参数并将其传递给reference,但是实际上调用了一个rvalue参数reference(int&)而不是reference(int &&),这里是我的代码片段:

#include <iostream>
#include <utility>
void reference(int& v) {
    std::cout << "lvalue" << std::endl;
}
void reference(int&& v) {
    std::cout << "rvalue" << std::endl;
}
template <typename T>
void pass(T&& v) {
    reference(v);
}
int main() {
    std::cout << "rvalue pass:";
    pass(1);

    std::cout << "lvalue pass:";
    int p = 1;
    pass(p);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

rvalue pass:lvalue
lvalue pass:lvalue
Run Code Online (Sandbox Code Playgroud)

因为p根据参考折叠规则很容易理解,但为什么模板函数传递v给reference()lvalue?

Rak*_*111 7

为什么模板函数传递v给reference()左值?

那是因为v是一个左值.等等,什么?v是一个右值参考.重要的是它是一个参考,因此是一个左值.它只与rvalues绑定并不重要.

如果要保留值类别,则必须进行完美转发.完美转发意味着如果你传递一个rvalue(就像你的情况一样),函数将被调用rvalue(而不是左值):

template <typename T>
void pass(T&& v) {
    reference(std::forward<T>(v)); //forward 'v' to 'reference'
}
Run Code Online (Sandbox Code Playgroud)


Whi*_*TiM 7

template <typename T>
void pass(T&& v) {
    reference(v);
}
Run Code Online (Sandbox Code Playgroud)

你在这里使用转发引用非常好,但事实上现在有一个名称v,它被认为是lvalue一个右值引用.

简单地说,任何有名字的东西都是lvalue.这就是为什么需要Perfect Forwarding,以获得完整的语义,使用std::forward

template <typename T>
void pass(T&& v) {
    reference(std::forward<T>(v));
}
Run Code Online (Sandbox Code Playgroud)

什么std::forward<T>只是做这样的事情

template <typename T>
void pass(T&& v) {
    reference(static_cast<T&&>(v));
}
Run Code Online (Sandbox Code Playgroud)

看到这个 ;