C++ 模板参数推导和表达式规则
关于这一点,我有一个后续问题: 注释C++ 模板参数推导和表达式规则,c++,templates,language-lawyer,c++20,C++,Templates,Language Lawyer,C++20,关于这一点,我有一个后续问题: 注释P和A请参阅本节 如果我正确理解模板参数推断,以下代码将发生以下情况: 模板 void foo(const T&a); int b; foo(std::move(b)); 首先,编译器分别为参数声明和模板参数推导出两种类型P和A。当声明是一个引用常量&(但不是转发引用)时,我们将对这种情况进行推导 对于A:std::move(b)具有调整为A:=int() 对于P:const T&->删除const和reference([])->P:=T 模式匹配A与P-
P
和A
请参阅本节
如果我正确理解模板参数推断,以下代码将发生以下情况:
模板
void foo(const T&a);
int b;
foo(std::move(b));
- 首先,编译器分别为参数声明和模板参数推导出两种类型
和P
。当声明是一个引用A
(但不是转发引用)时,我们将对这种情况进行推导常量&
- 对于
:A
具有调整为std::move(b)
()A:=int
- 对于
:P
->删除const和reference([])->const T&
P:=T
- 模式匹配
与A
->结果P
T:=int
std::move(b)
是一个表达式,我一直认为它的类型是int&
(因为std::move
返回一个int&&
),但是()告诉了一些不同的东西,这意味着在任何分析发生之前删除每个引用,所以当我们谈论表达式的类型时,从未涉及任何参考:struct A{A&operator+(const A&);}
A,b;
自动c=a+b;
因此a+b
显然返回aa&
。但是表达式的类型是A
。对吗declval(a+b)
是另一个野兽,返回a&
function return type function call expression [type,value-category]
T& => [ T , lvalue ]
T&& => [ T , xvalue ]
T => [ T , prvalue ]
decltype
进行反向映射:
对于表达式e,decltype(e)表示的类型定义如下:
- [……]
- 否则,如果e是xvalue,decltype(e)是T&&,其中T是e的类型
- 否则,如果e是左值,decltype(e)是T&,其中T是e的类型
- 否则,decltype(e)就是e的类型
因此,在[expr.type]中删除引用不会丢失引用带给类型的信息。此信息由值类别表示。
A&operator+(const A&)代码>看起来很奇怪。不一定违法,但肯定很奇怪。这对你的问题并不重要。我知道,回信不是很好,这显然是错误的,但只是作为一个例子来证明我的观点。:)有一些关于引用表达式如何工作的信息declval(…)
出于同样的原因不返回引用类型。仍然让我困惑的是:int&&a;a代码>表达式的类型是什么a代码>。它是一个id表达式
并且它的类型是int&
?@Gabriel,a
的类型与它的声明中指定的类型完全相同:int&
。(其价值类别为左值。)@Gabriel。id表达式总是左值。表达式a
的类型为int
,值类别为lvalue
。分离变量的声明类型和仅为该变量名称的表达式类型的概念非常重要。也许这个Q&A会有所帮助:所以你基本上参考了fordecltype(A)
。这是正确的吗?@Gabriel我的意思是decltype(a)
不提供id表达式a
的类型和值类别的信息,但提供id表达式a
表示的变量类型的信息(声明的a
)。