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;
}
输出是:
rvalue pass:lvalue
lvalue pass:lvalue
对于p
,根据参考折叠规则很容易理解,但为什么模板功能会将v
传递给reference()
作为左值?
答案 0 :(得分:7)
为什么模板函数将
v
传递给reference()
作为左值?
那是因为v
是一个左值。等等,什么? v
是右值参考 。重要的是它是一个参考,因此是一个左值。它只与rvalues有关并不重要。
如果您想保留值类别,则必须执行完美转发。完美转发意味着如果你传递一个rvalue(就像你的情况一样),那么函数将被调用rvalue(而不是左值):
template <typename T>
void pass(T&& v) {
reference(std::forward<T>(v)); //forward 'v' to 'reference'
}
答案 1 :(得分:7)
template <typename T>
void pass(T&& v) {
reference(v);
}
您在这里使用转发引用非常好,但事实上现在有一个名称v
,它被视为右值引用的lvalue
简而言之,任何名称都是lvalue
。这就是为什么需要Perfect Forwarding来获得完整的语义,使用std::forward
template <typename T>
void pass(T&& v) {
reference(std::forward<T>(v));
}
std::forward<T>
做的只是做这样的事情
template <typename T>
void pass(T&& v) {
reference(static_cast<T&&>(v));
}
见this;