14

(由答案提示。)

给定 N3290,§7.1.6.2p4,其中列表项未编号,但为方便起见在此处编号:

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

  1. 如果 e 是不带括号的 id 表达式或不带括号的类成员访问 (5.2.5),则 decltype(e) 是由 e 命名的实体的类型。如果没有这样的实体,或者如果 e 命名了一组重载函数,则程序是非良构的;
  2. 否则,如果 e 是一个 xvalue,则 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 是某些涉及右值引用的表达式的结果 (8.3.2)。

我在 §8.3.2 中看不到任何有用的东西,但我知道“0 + 0”不涉及任何右值引用。文字 0 是一个纯右值,它是“一个不是 xvalue 的右值”(§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&& 类型,那么它的格式就不是很好。

4

5 回答 5

10

0 + 0是两个纯右值(n3290 par. 3.10)的表达式,它应用内置的operator+,根据 13.6/12 是LR operator+(L,R),因此它是一个返回不是引用的东西的函数。因此,表达式的结果也是一个纯右值(根据 3.10)。

因此, 0 + 0 的结果是一个纯右值, 0 是一个int,因此 0 + 0 的结果是一个int

于 2011-05-08T02:55:29.880 回答
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
于 2011-05-08T03:13:16.767 回答
2

你的推理是正确的。只涉及常量的表达式本身就是一个常量。因此

decltype(0 + 0) x;

等于

decltype(0) x;

这等于

int x;
于 2011-05-08T01:02:13.183 回答
2

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

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

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

于 2011-05-30T19:20:08.467 回答
0

海湾合作委员会说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,所以这就是声明的类型。

于 2011-05-08T00:48:04.923 回答