Fre*_*urk 14 c++ rvalue decltype xvalue c++11
(答案提示.)
鉴于N3290,§7.1.6.2p4,其中列表项目未编号,但为了方便我们编号:
decltype(e)表示的类型定义如下:
- 如果e是未表示的id-expression或未加密的类成员访问(5.2.5),则decltype(e)是e所命名的实体的类型.如果没有这样的实体,或者如果e命名了一组重载函数,那么该程序就会形成错误;
- 否则,如果e是x值,则decltype(e)是T &&,其中T是e的类型;
- 否则,如果e是左值,则decltype(e)是T&,其中T是e的类型;
- 否则,decltype(e)是e的类型.
decltype(0 + 0)指定的类型是什么?
第1项不适用,2可能,但如果没有,则3不适用,4将是结果.那么,什么是xvalue,是0 + 0和xvalue?
§3.10p1:
xvalue("eXpiring"值)也指对象,通常接近其生命周期的末尾(例如,可以移动其资源).xvalue是涉及rvalue引用的某些表达式的结果(8.3.2).
我在§8.3.2中没有看到任何有用的内容,但我知道"0 + 0"不涉及任何右值引用.文字0是一个prvalue,它是"一个不是xvalue的rvalue"(§3.10p1).我相信"0 + 0"也是一个prvalue.如果这是真的,"decltype(0 + 0)"将是int(不是int &&).
我的解释错过了什么吗?这段代码是否格式良好?
decltype(0 + 0) x; // Not initialized.
Run Code Online (Sandbox Code Playgroud)
该代码编译在GCC 4.7.0 20110427和Clang 2.9(主干126116)上.例如,如果decltype指定了int &&类型,那么它将不会格式良好.
rlc*_*rlc 10
0 + 0
是两个prvalues的表达式,(n3290参数3.10),它应用内置的operator+
,每13.6/12是LR operator+(L,R)
一个函数,返回一个不是引用的东西.因此,表达式的结果也是prvalue(根据3.10).
因此,0 + 0的结果是prvalue,0是a int
,因此0 + 0的结果是aint
这肯定是一个int:
#include <iostream>
#include <typeinfo>
template<typename T>
struct ref_depth
{
enum { value = 0 };
};
template<typename T>
struct ref_depth<T&>
{
enum { value = 1 };
};
template<typename T>
struct ref_depth<T&&>
{
enum { value = 2 };
};
int main() {
std::cout
<< "int: " << typeid(int).name() << "\n"
"decltype(0 + 0): " << typeid(decltype(0 + 0)).name() << "\n"
"int&&: " << typeid(int&&).name() << "\n";
std::cout
<< "ref_depth: int: " << ref_depth<int>::value << "\n"
"ref_depth: decltype(0 + 0): " << ref_depth<decltype(0 + 0)>::value << "\n"
"ref_depth: int&&: " << ref_depth<int&&>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)
输出:
int: i
decltype(0 + 0): i
int&&: i
ref_depth: int: 0
ref_depth: decltype(0 + 0): 0
ref_depth: int&&: 2
Run Code Online (Sandbox Code Playgroud)
从 5.19 开始[expr.const]
,每个文字常量表达式都是纯右值。
文字常量表达式是文字类型的纯右值核心常量表达式,但不是指针类型。整型常量表达式是整型或无范围枚举类型的文字常量表达式。
因此规则 4 适用于所有文字常量表达式。