可能重复:
decltype and parenthesis
int i=6;
decltype((i)) var5 = i; // int&
我只是不明白为什么括号中的'i'被认为是Lvalue,现在,我知道括号的应用,直到我在MSDN中发现:内括号导致语句被评估为表达式而不是成员访问。(http://msdn.microsoft.com/en-us/library/dd537655.aspx),我也不理解我很长时间没有理解的问题。
template<typename T>
class B
{
public:
B(T t){printf("B\n");}
};
template <typename T >
void ft(T t)
{
t.f();
}
int _tmain(int argc, _TCHAR* argv[])
{
B<A> b1(A()); //one function declaration, A() is regarded as fun-ptr, and b1 is a function
B<A> b2((A())); //A() is regarded as anonymous object.
return 0;
}
为什么将A()
作为(A())
放在括号中时将其视为匿名对象。关于MSDN中decltype的内括号解释不适用于这种情况。有人可以告诉我,在C ++标准的这两种情况下,括号功能是否有扩展。我应该如何更好地理解这一点,非常感谢!
答案 0 :(得分:2)
那些情况确实完全不同。
B<A> b1(A());
这是一个函数声明,因为它遵循语法生成“return-type identifier'('parameter-declaration-list')'”,其中parameter-declaration-list是以逗号分隔的参数声明列表。这种声明的产生是“type abstract-declarator [opt]”。除其他外,abstract-declarator可以为空,或者是“'('abstract-declarator')'”。所以“A()”匹配一个类型(A),后跟包含空格式abstract-declarator的abstract-declarator的括号形式。因此,代码在语法上是一个有效的函数声明,并被解析为。
B<A> b1((A()));
这里,如果我们想要去函数声明路径,我们需要将“(A())”与参数声明匹配;但是,没有办法做到这一点。所以这不是函数声明,因此必须是带有直接初始化器的变量声明。
另一种情况在语法上是明确的。 decltype(i)和decltype((i))都是简单的decltype派生。在第一种情况下,语法树是DeclType(DeclRefExpression(“i”)),在第二种情况下,它是DeclType(ParenExpression(DeclRefExpression(“i”)))。
这里的特殊部分是decltype的规则。 decltype规则如下:
在decltype(i)中,表达式是对i的declref。 i的类型是int。因此,decltype(i)是“int”。 在decltype((i))中,表达式是parenexpr。括号中包含的内容无关紧要 - 规则1和规则2都不适用。但是,(i)是左值,因此适用第3条。 (i)的类型是int,因此decltype((i))是“int&amp;”。