decltype和lvalue表达式

时间:2013-04-12 07:29:27

标签: c++ c++11 lvalue decltype

根据http://en.cppreference.com/w/cpp/language/decltype

struct A {
    double x;
};
const A* a = new A();

decltype( a->x ) x3;

匹配1个案例,即:

如果参数是对象/函数的未加特征化的名称,或者是成员访问表达式(object.member或pointer->成员),则decltype指定声明的类型此表达式指定的实体。

但请注意:

  

如果对象的名称带括号,则它变为左值表达式

引导我提出以下问题:如果a->x不是左值表达式,那么decltype((a->x)) x4 = x3; // type of x4 is const double& (lvalue expression) 的类型是什么?

我甚至不明白为什么

const&

仅作为{{1}}被评估为被认为是左值表达式,并没有真正看到链接。

2 个答案:

答案 0 :(得分:3)

  

告诉我以下问题a-> x的类型是什么,如果它不是左值表达式?

你只是感到困惑。

  

如果对象的名称带括号,则它变为左值表达式

那应该是

  

如果对象的名称带括号,则由decltype处理不同的对象。

括号和非括号内容都是左值表达式。如果没有括号,则decltype不会检查表达式的类型,而是检查名称查找名称所引用的声明所使用的类型(例如,如果名称查找,它可能是int&&将其解析为右值引用变量,但表达式的类型为int,并且是左值)。

答案 1 :(得分:2)

考虑它的方法是(恕我直言)这个:

decltype( a->x )

保留/检索x引用成员变量的信息,因此它为您提供了成员变量的声明类型。这很有用,因为如果自动转换为下一个案例,您将无法提取该信息:

decltype( (a->x) )

这是“只是”一个表达式,因此表现得像任何其他表达式。它指的是表达式返回,而不是表达式引用。表达式是一个左值,它是一个成员变量并不重要。您明确地丢弃了可用的部分信息,表达了您对对象/成员被声明的内容不感兴趣的意图,但仅限于表达式的结果类型。

换句话说:第一种语法为您提供更多信息,除非显式决定您不需要它们并使用第二种语法。