繁体   English   中英

C ++如何在rvalue引用上进行模板推导?

[英]How does C++ make template deduction on rvalue reference?

template<typename T>
void foo(T&& arg);

我知道arg是否是左值,例如int x = 0; foo(x); 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 ,它的“reference-ness”会被忽略,就像往常一样。

暂时忘掉左值和右值和模板。 引用应该是另一个变量的别名 ,并且在大多数情况下,引用按名称引用的行为应该就像引用原始变量一样:

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-expression irint类型的左值。 变量 ir分别是非引用和引用的事实与相应的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

它应该是U最终存在的任何东西,所以如果U是一个int,它就是

bar(int&& u)
{
    foo(u);
}

将int传递给foo。

如果我有

template<typename T>
void foo(T& arg);

template<typename U>
void bar(U&& u)
{
    foo(u);
}

在调用bar(0)时,foo中的T是什么?

它可能听起来有点出乎意料,但是使用rvalue-reference是一个左值表达式,这意味着ufoo(u)是一个左值,并且调用一个带左值引用的函数是完全正确的(在此案件foo

也就是说,对于调用bar(0) ,使用的专业化将是:

bar<int>(int&&)
foo<int>(int&)

对于int value; bar(value); int value; bar(value); ,专业将是:

bar<int&>(int& &&) // i.e. int&
foo<int>(int&)

暂无
暂无

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

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