template<typename T>
void foo(T&& arg);
我知道 arg 是否是左值,例如int x = 0; foo(x);
然后 T = int&
函数将是 foo(int& &&)
,即 foo(int&)
.
如果 arg 是右值,例如foo(0)
;然后 T = int
函数将是 foo(int&&)
。
如果我有呢
template<typename T>
void foo(T& arg);
template<typename U>
void bar(U&& u)
{
foo(u);
}
当调用 bar(0)
时,foo
中的 T
是什么?
最佳答案
template<typename U>
void bar(U&& u)
{
foo(u);
}
无论您向 bar
传递什么,u
都是左值,因为它有一个名称。
u
可能是左值引用或右值引用,但是当您将它传递给 foo
时,它的“引用性”会像往常一样被忽略。
暂时忘掉左值、右值和模板。引用应该是另一个变量的别名,并且在大多数情况下,按名称引用引用的行为应该与引用原始变量一样:
int i = 42;
int& r = i;
f(int);
f(int&);
f(i); // error: call to ambiguous overload
f(r); // error: call to ambiguous overload
g(int);
g(r); // OK, pass by copy, reference-ness of r is irrelevant
h(int&);
h(i); // OK, pass by reference, non-reference-ness of i is irrelevant
在上面的函数调用语句中,id-expressions i
和 r
是 int
类型的左值. 变量 i
和 r
分别是非引用和引用的事实与相应的类型或值类别无关id 表达式。这是引用一直以来的工作方式,右值引用不会改变这一点。
template<typename T>
void foo(T& arg);
没有任何东西可以传递给 foo
使 T
成为引用类型。 arg
将始终是左值引用。
如果你想传播参数的值类别,你需要std::forward
:
template<typename U>
void baz(U&& u)
{
foo(std::forward<U>(u));
}
baz(42); // error: attempted to call foo() with an rvalue
关于c++ - C++如何对右值引用进行模板推导?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26394261/