让foo
成为函数:
template< typename T >
void foo( T&& a ){}
T
以下调用将foo
推断出哪种类型:
foo( 0 ); // is T here int or int&& ?
int a = 0;
foo( a ); // is T here int or int& ?
答案 0 :(得分:5)
类型推导的默认规则是引用类型永远不会是推论的结果。鉴于此代码,
template <class T>
void bar(T par);
bar(0);
int a;
bar(a);
int &b;
bar(b);
所有3个电话都会拨打foo<int>
。也就是说,T
推断为int
而par
的推断类型为int
。
通过简单添加一个规则来转发引用工作:当用于类型推导转发引用的参数时(即推导出的参数T&&
T
)是X
类型的左值,使用类型X &
代替X
进行演绎。
请注意,这意味着在X
类型的情况下,只有X
或X &
才能成为类型扣除的结果; X &&
永远不会。
让我们分析您的代码(我将重命名他的函数参数,以明确我所指的内容):
template <class T>
void foo(T &&par);
foo(0);
int a;
foo(a);
在第一种情况foo(0)
中,参数是类型int
的右值。因此类型int
用于类型推导,这意味着T
被推导为{ {1}}(调用的函数为int
),foo<int>
的类型为par
。
在第二种情况int &&
中,参数是foo(a)
类型的左值。转发参考规则启动,类型int
用于扣除。因此,int &
推断为T
(名为int &
的函数),foo<int&>
的类型为&#34; par
&#34;,折叠为int & &&
。
答案 1 :(得分:1)
foo(0); //这里是T或者int&amp;&amp; ?
int
。
int a = 0; foo(a); //这里的T是int还是int&amp; ?
int&
。
答案 2 :(得分:1)
推断的上下文中的表达式T&&
与您提供的内容一样
template< typename T >
void foo( T&& a ){}
即T是根据提供的参数推导出来的,受制于 reference collapsing rules
简而言之;
如果提供的参数是type
类型的左值,T&&
将展开为type& &&
折叠为type&
如果提供的参数是type
类型的右值,T&&
将展开为type &&
折叠为type&&
如果您需要触发右值,请注意两者都是引用
另一个函数的重载,你需要做std::forward<T>(a)