简体   繁体   English

为什么右值引用作为左值引用传递?

[英]Why rvalue reference pass as lvalue reference?

pass() reference argument and pass it to reference , however a rvalue argument actually called the reference(int&) instead of reference(int &&) , here is my code snippet: pass()引用参数并将其传递给reference ,但是右值参数实际上称为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;
}

the output is:输出是:

rvalue pass:lvalue
lvalue pass:lvalue

For p it is easy to understand according to reference collapsing rule , but why the template function pass v to reference() as lvalue?对于p ,根据引用折叠规则很容易理解,但是为什么模板函数将v作为左值传递给reference()呢?

Why the template function pass v to reference() as lvalue?为什么模板函数将v作为左值传递给reference()

That's because v is an lvalue.那是因为v是一个左值。 Wait, what?等等,什么? v is an rvalue reference . v是一个右值引用 The important thing is that it is a reference, and thus an lvalue.重要的是它是一个引用,因此是一个左值。 It doesn't matter that it only binds to rvalues.它只绑定到右值并不重要。

If you want to keep the value category, you will have to do perfect forwarding .如果要保留价值类别,则必须进行完美转发 Perfect forwarding means that if you pass an rvalue (like in your case), the function will be called with an rvalue (instead of an lvalue):完美转发意味着如果你传递一个右值(就像你的情况一样),函数将被一个右值(而不是一个左值)调用:

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

You are using a Forwarding reference here quite alright, but the fact that there is now a name v , it's considered an lvalue to an rvalue reference .您在这里使用 Forwarding 引用非常好,但事实上现在有一个名称v ,它被认为是右值引用lvalue

Simply put, anything that has a name is an lvalue .简而言之,任何有名字的东西都是lvalue This is why Perfect Forwarding is needed, to get full semantics, use std::forward这就是需要完美转发的原因,要获得完整的语义,请使用std::forward

template <typename T>
void pass(T&& v) {
    reference(std::forward<T>(v));
}

What std::forward<T> does is simply to do something like this std::forward<T>所做的只是做这样的事情

template <typename T>
void pass(T&& v) {
    reference(static_cast<T&&>(v));
}

See this ;看到这个

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM