(由an answer提示。)
鉴于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.
该代码在GCC 4.7.0 20110427和Clang 2.9(主干126116)上编译。如果decltype指定了int&&&例如,输入。
答案 0 :(得分:10)
0 + 0
是两个prvalues的表达式,(n3290 par.3.10),它应用内置的operator+
,每13.6 / 12是LR operator+(L,R)
,因此是返回不是引用的东西的函数。因此,表达式的结果也是一个prvalue(根据3.10)。
因此,0 + 0的结果是prvalue,0是int
,因此0 + 0的结果是int
答案 1 :(得分:5)
绝对是一个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";
}
输出:
int: i
decltype(0 + 0): i
int&&: i
ref_depth: int: 0
ref_depth: decltype(0 + 0): 0
ref_depth: int&&: 2
答案 2 :(得分:2)
你的推理是正确的。仅涉及常量的表达式本身就是一个常量。因此
decltype(0 + 0) x;
等于
decltype(0) x;
等于
int x;
答案 3 :(得分:2)
从5.19 [expr.const]
开始,每个文字常量表达式都是prvalue。
文字常量表达式是文字类型的prvalue核心常量表达式,但不是指针类型。 整数常量表达式是整数或未整数枚举类型的文字常量表达式。
因此,规则4适用于所有文字常量表达式。
答案 4 :(得分:0)
GCC说int
-
代码:
#include <iostream>
#include <typeinfo>
int
main ()
{
int n;
decltype(0 + 0) x;
std::cout << "Type of `n': " << typeid(n).name() << std::endl;
std::cout << "Type of `x': " << typeid(x).name() << std::endl;
}
输出:
我
我
编辑:根据第4点,它是有道理的,但我不能肯定地说第2点实际上并不是有效的。据我所知,0 + 0被评估为0,0的类型是int
,因此这是声明的类型。