2017-02-21 131 views
2

我发现它们不同,语言标准说明每个语句应该检索哪种类型(变量和表达式之间的区别)。但我真的很想知道为什么这两种类型应该有所不同?C++ 11为什么'decltype(x)'和'decltype((x))'的类型不同?

#include<stdio.h> 
int x=0; 
decltype((x)) y=x; 
int main() 
{ 
    y=2; 
    printf("%d,",x); 
    decltype((1+2))&z=x;//OK (1+2) is an express, but why decltype should differ? 
    z=3; 
    printf("%d\n",x); 
    return 0; 
} 

运行结果是 '2,3'

那么,为什么decltype((INT))是由设计INT &,什么是C的代价++语言的设计在这里?任何需要这种设计的语法一致性? (我不希望得到“This is by design”)

感谢您的解释。

+0

@some我没有看到有关的解释 –

+0

@ JohannesSchaub-litb添加了报价的答案 –

+1

您最好的机会是阅读“decltype”的提议,我想。谷歌搜索“decltype wg21提案”给出了一些有趣的论文。 –

回答

1

如果您阅读例如this decltype reference你会看到

2)如果参数为加括号 ID-表达或加括号类成员访问表达式,...

3)如果参数为任何其他表达 ...

... b)如表达式的值类别是左值,然后decltype产量T&;

[重点煤矿]

再稍进一步下跌的音符

注意,如果一个对象的名称括弧,它是作为一个普通的左值表达式处理,因此decltype(x)decltype((x))通常是不同的类型。

因为您使用括号表达式它被视为一个左值,这意味着上述3.B是活性和decltype((x))给你int&如果xint

应该指出的是,尽管参考文献并非权威性的,但是它是从规范中推导出来的,并且通常可靠和正确。


从C++ 11规范ISO/IEC 14882:2011,节7.1.6.2 [dcl.type.simple],子部分4:

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

- 如果e是一个括号的ID-表达或加括号的类的成员访问(5.2.5),decltype(e)是由e命名实体的类型。如果没有这样的实体,或者如果命名一组重载函数,则该程序是不合格的;

- 否则,如果e是一个x值,decltype(e)T&&,其中Te类型;

- 否则,如果e是左值,decltype(e)T&,其中Te类型;

- 否则,decltype(e)e

的类型和用一个例子:

struct A { double x; }; 
const A* a = new A(); 
... 
decltype((a->x)) x4 = x3; // type is const double& 

基本上正是以前链接参考所述。

以您为例,规范中的e(x)(因为您有declspec((x)))。现在第一个案件不适合,因为(x)不是一个不亲密的表达式。第二种情况不适合,因为(x)不是xvalue。第三种情况匹配,但(x)int类型的左值,导致decltype((x))int&

因此,对您的查询的答案很简单:因为规范是这样说的。

+0

我在这里看不到这种行为的解释。 –

+0

谢谢,但我在这里没有看到任何解释,这只是我的问题的复制,我问他们为什么不同? –

+0

@HindForsum午餐后我会尽量从规范中找到相关部分。但你会看到他们说的是一样的。所以*真实*答案将仅仅是:因为规范说明了这一点! –

相关问题