什么是decltype(0 + 0)?

时间:2011-05-08 00:21:44

标签: c++ c++11 rvalue decltype xvalue

(由an answer提示。)

鉴于N3290,§7.1.6.2p4,其中列表项目未编号,但为了方便我们编号:

  

由decltype(e)表示的类型定义如下:

     
      
  1. 如果e是未加密码的id-expression或不加括号的类成员访问(5.2.5),则decltype(e)是e命名的实体的类型。如果没有这样的实体,或者e命名了一组重载函数,那么该程序就是格式不正确的;
  2.   
  3. 否则,如果e是x值,则decltype(e)是T&&,其中T是e的类型;
  4.   
  5. 否则,如果e是左值,则decltype(e)是T&,其中T是e的类型;
  6.   
  7. 否则,decltype(e)是e的类型。
  8.   

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&&&例如,输入。

5 个答案:

答案 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,因此这是声明的类型。