根据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}}被评估为被认为是左值表达式,并没有真正看到链接。
答案 0 :(得分:3)
告诉我以下问题a-> x的类型是什么,如果它不是左值表达式?
你只是感到困惑。
如果对象的名称带括号,则它变为左值表达式
那应该是
如果对象的名称带括号,则由decltype处理不同的对象。
括号和非括号内容都是左值表达式。如果没有括号,则decltype不会检查表达式的类型,而是检查名称查找名称所引用的声明所使用的类型(例如,如果名称查找,它可能是int&&
将其解析为右值引用变量,但表达式的类型为int
,并且是左值)。
答案 1 :(得分:2)
考虑它的方法是(恕我直言)这个:
decltype( a->x )
保留/检索x
引用成员变量的信息,因此它为您提供了成员变量的声明类型。这很有用,因为如果自动转换为下一个案例,您将无法提取该信息:
decltype( (a->x) )
这是“只是”一个表达式,因此表现得像任何其他表达式。它指的是表达式返回,而不是表达式引用。表达式是一个左值,它是一个成员变量并不重要。您明确地丢弃了可用的部分信息,表达了您对对象/成员被声明的内容不感兴趣的意图,但仅限于表达式的结果类型。
换句话说:第一种语法为您提供更多信息,除非显式决定您不需要它们并使用第二种语法。