Gab*_*iel 4 c++ templates language-lawyer c++20
我有一个关于这个问题的后续问题:符号P并A参考temp.deduct.call部分
如果我正确理解模板参数推导,则以下代码会发生以下情况:
template<typename T>
void foo(const T& a);
int b;
foo(std::move(b));
Run Code Online (Sandbox Code Playgroud)
P和。我们正在推论声明是引用(但不是转发引用)A的情况const T&A:std::move(b)类型为int&&[xvalue] -> 调整为A:= int( [7.2.2#1] )P:const T&-> 删除 const 和引用 ([ 12.9.2.1#3 ]) ->P:= TA- P > 结果T:= int。两个问题:
std::move(b)是一个表达式,我一直认为它的类型是int&&(因为std::move返回 a int&&),但是 ( [7.2.2#1] ) 告诉了一些不同的事情,这意味着在进行任何分析之前删除每个引用,所以当人们谈论表达式的类型时,从来没有涉及任何参考:struct A{ A& operator+(const A&);}
A a, b;
auto c = a + b;
Run Code Online (Sandbox Code Playgroud)
所以a+b显然返回一个A&. 但表达式的类型是A. 那是对的吗 ?declval(a+b)是另一只野兽,并返回A&。
该引用已从表达式类型中删除。但是表达式有另一个属性,value-category ,它映射到函数调用表达式[expr.call]/14 的引用类型:
如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值;如果结果类型是对对象类型的右值引用,则函数调用是 xvalue;否则是纯右值。
这几乎可以用那些推理规则来表示:
function return type function call expression [type,value-category]
T& => [ T , lvalue ]
T&& => [ T , xvalue ]
T => [ T , prvalue ]
Run Code Online (Sandbox Code Playgroud)
decltype进行反向映射,[dcl.type.decltype]/1:
对于表达式 e,decltype(e) 表示的类型定义如下:
- [...]
否则,如果 e 是 xvalue,则 decltype(e) 是 T&&,其中 T 是 e 的类型;
否则,如果 e 是左值,则 decltype(e) 是 T&,其中 T 是 e 的类型;
否则,decltype(e) 是 e 的类型。
因此,通过引用为类型带来的信息不会因删除 [expr.type] 中的引用而丢失。该信息由值类别表示。
| 归档时间: |
|
| 查看次数: |
167 次 |
| 最近记录: |