首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >T& in模板函数和类

T& in模板函数和类
EN

Stack Overflow用户
提问于 2012-09-07 18:12:00
回答 2查看 581关注 0票数 1

我刚刚偶然发现了T&&在类和函数中的含义是不同的。

职能:

代码语言:javascript
复制
template<class T> void f(T&& t){};   // t is R or L-value
...
int i=0; 
f(i);   // t in f is lvalue
f(42);  // t in f is rvalue  

在课堂上:

代码语言:javascript
复制
template<class T> 
struct S { 
       S(T&& t){}  // t is only R-value? 
};
...
int i;
S<int> ss(i);   // compile error - cannot bind lvalue to ‘int&&’

这是否意味着如果我们在类中有T&& t,那么t只会是rvalue吗?

有谁能帮我找到更多关于这方面的信息吗?

这是否意味着我需要为L和R值编写两个方法重载?

答案

正如Alf的示例所示,函数和类中的t可以是Lvalue或Rvalue。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-07 18:15:06

在您的函数中,T是从实际参数中推导出来的。这种特殊组合的主要用途是完美转发。在类模板T中,必须指定它。

例如,这与g++和msvc都编译得很好:

代码语言:javascript
复制
template<class T> 
struct S { 
       S(T&& t){}
};

int main()
{
    int i;
    S< int& > ss(i);
}
票数 2
EN

Stack Overflow用户

发布于 2012-09-07 18:16:39

您在这里处理的是模板参数推导。

通过在不显式定义模板参数的情况下使用f,C++编译器现在必须从传递它的参数中确定模板参数类型T

使用&&类型的模板参数演绎规则是允许完美转发的特殊规则。当您使用f(i)时,T被推断为T&。因此,参数t的类型为T& &&,它折叠为T&。但是,当您使用f(42)时,T类型被推断为T&&,因此tT&& &&,它折叠为T&&

一旦您强制T成为特定类型,所有这些实际上都会消失。崩溃仍然可能发生,但是由于您使用了S<int>,那么t将是int&&类型。S<int> ss(i)实际上相当于f<int>(i),这也是不合法的。而且,由于模板参数演绎只适用于函数而不适用于类型,因此,如果您想要完美的转发,就必须为S执行类似的操作:

代码语言:javascript
复制
template<class T> 
struct S { 
    template<class U>
    S(U&& t){}
};

当然,您可以使用SFINAE方法和模板元编程来确保只有在TU的基本类型相同的情况下才能实例化构造器模板。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12323308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档