什么是decltype(0 + 0)?

Fre*_*urk 14 c++ rvalue decltype xvalue c++11

(答案提示.)

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

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

  1. 如果e是未表示的id-expression或未加密的类成员访问(5.2.5),则decltype(e)是e所命名的实体的类型.如果没有这样的实体,或者如果e命名了一组重载函数,那么该程序就会形成错误;
  2. 否则,如果e是x值,则decltype(e)是T &&,其中T是e的类型;
  3. 否则,如果e是左值,则decltype(e)是T&,其中T是e的类型;
  4. 否则,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

  • 内置运算符不是函数调用.所以你不能拿13.6/12并得到那些候选的描述返回类型并将它们应用到第5节.那些13.6的候选只有当你做重载解析时才有效且相关(如果至少有一个操作数属于类或枚举类型) ).它们仅用于转换类类型的操作数.完成之后,控制完全返回到第5节."LR运算符+"不是以某种方式调用的实际函数. (4认同)
  • §13.6p9是*一元*运算符+.你想要§13.6p12.但是,草案说"这些候选函数参与了13.3.1.2中描述的运算符重载解析过程,并且没有用于其他目的." (§13.6p1)我认为"没有其他目的"意味着我们不能用它们来确定价值类别.无论如何,+1都是一个好的答案. (2认同)

Kha*_*sar 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";

}
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)

  • 你能否在答案中加入代码?(而不是在答案中总结代码的结论并链接到完全不同的网站.) (2认同)

Ben*_*igt 2

从 5.19 开始[expr.const],每个文字常量表达式都是纯右值。

文字常量表达式是文字类型的纯右值核心常量表达式,但不是指针类型。整型常量表达式是整型或无范围枚举类型的文字常量表达式。

因此规则 4 适用于所有文字常量表达式。

  • 你有这个倒退:该段落是**定义**术语*文字常量表达式*。 (2认同)