了解通用引用的类型推导

时间:2017-10-04 08:17:11

标签: c++ function templates type-deduction forwarding-reference

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& ?

3 个答案:

答案 0 :(得分:5)

类型推导的默认规则是引用类型永远不会是推论的结果。鉴于此代码,

template <class T>
void bar(T par);

bar(0);
int a;
bar(a);
int &b;
bar(b);

所有3个电话都会拨打foo<int>。也就是说,T推断为intpar的推断类型为int

通过简单添加一个规则来转发引用工作:当用于类型推导转发引用的参数时(即推导出的参数T&& T)是X类型的左值,使用类型X &代替X进行演绎。

请注意,这意味着在X类型的情况下,只有XX &才能成为类型扣除的结果; 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)