C ++ 11为什么'decltype(x)'和'decltype((x))'的类型不同? [英] C++11 why the type of 'decltype(x)' and 'decltype((x))' are different?

查看:166
本文介绍了C ++ 11为什么'decltype(x)'和'decltype((x))'的类型不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现它们是不同的,并且语言标准规定了每个语句应检索的类型(变量和表达式之间的差异)。但是我真的很想知道为什么这两种类型应该有所不同?

I found they're different, and the language standard says what kind of type each statement should retrieve(difference between variable and expression). But I really wish to know why these 2 kinds of types should be different?

#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 ++语言设计考虑什么?需要这种设计的语法一致性吗? (我不想得到这是设计使然)

So why decltype((int)) is int& by design, what's the consideration of C++ language design here? Any syntax consistency that requires such a design? (I don't wish to get "This is by design")

感谢您的解释。

推荐答案

如果您阅读例如 decltype 参考您将看到

If you read e.g. this decltype reference you will see


2)如果参数是 unparenthesized id表达式或 unparenthesized 类成员访问表达式,...

2) If the argument is an unparenthesized id-expression or an unparenthesized class member access expression, ...

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

3) If the argument is any other expression...

...
b),如果 expression 的值类别为左值,则 decltype 会产生 T& ;

... b) if the value category of expression is lvalue, then decltype yields T&;

[强调矿井]

然后再往下走一点


请注意,如果名称将对象的括号括起来,将其视为普通的左值表达式,因此 decltype(x) decltype((x))通常是不同的类型。

Note that if the name of an object is parenthesized, it is treated as an ordinary lvalue expression, thus decltype(x) and decltype((x)) are often different types.

由于使用带括号的表达式,因此将其视为左值,这意味着上面的3.b是活动的,而 decltype((x))如果 x 为<$ c,则为 int& $ c> int 。

Because you use a parenthesized expression it is treated as an lvalue, meaning that 3.b above is active and decltype((x)) gives you int& if x is int.

应该注意的是,尽管该参考文献不是权威性的,但它源自规范,并且通常可靠且正确。

It should be noted that while the reference isn't authoritative it is derived from the specification and generally reliable and correct.

根据C ++ 11规范ISO / IEC 14882:2011,第7.1.6.2节[dcl.type。简单],第4节:

From the C++11 specification ISO/IEC 14882:2011, section 7.1.6.2 [dcl.type.simple], sub-section 4:


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

-如果 e 是未括号化的id表达式或未括号化的类成员访问( 5.2.5)中, decltype(e)是由 e 命名的实体的类型。如果没有这样的实体,或者如果 e 命名一组重载函数,则程序的格式不正确;

— if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;

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

— otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;

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

— otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;

-否则, decltype(e) e

并举例说明:


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


基本上与先前链接的参考文献完全相同。

Basically exactly what the previously linked reference said.

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

With your example, e in the specification is (x) (since you have declspec((x))). Now the first case doesn't fit because (x) is not an unparenthesized expression. The second case doesn't fit because (x) isn't an xvalue. The third case matches though, (x) is an lvalue of type int, leading decltype((x)) to be int&.

因此,您的答案查询很简单:因为规范如此。

So the answer to your query is simply: Because the specification says so.

这篇关于C ++ 11为什么'decltype(x)'和'decltype((x))'的类型不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆