【问题标题】:C++11 why the type of 'decltype(x)' and 'decltype((x))' are different?C++11 为什么'decltype(x)'和'decltype((x))'的类型不同?
【发布时间】:2017-02-21 09:11:47
【问题描述】:

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

#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&amp;,这里C++ 语言设计的考虑是什么?任何需要这种设计的语法一致性? (我不希望得到“这是设计使然”)

感谢您的解释。

【问题讨论】:

  • @some 我没有看到解释
  • @JohannesSchaub-litb 添加了带引号的答案
  • 我认为你最好的机会是阅读“decltype”的建议。谷歌搜索“decltype wg21 proposal”给出了一些有趣的论文。

标签: c++11 variables types expression decltype


【解决方案1】:

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

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

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

... b) 如果表达式的值类别是左值,那么decltype产生T&amp;

[强调我的]

然后再往下一点

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

因为您使用带括号的表达式,所以它被视为左值,这意味着上面的 3.b 处于活动状态,如果 xintdecltype((x)) 会为您提供 int&amp;

需要注意的是,虽然参考文献不具有权威性,但它源自规范,通常可靠且正确。


来自 C++11 规范 ISO/IEC 14882:2011,第 7.1.6.2 节 [dcl.type.simple],第 4 小节:

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

——如果e是一个无括号的id-expression或一个无括号的类成员访问(5.2.5),decltype(e)e命名的实体的类型。如果没有这样的实体,或者如果e 命名了一组重载函数,则程序是非良构的;

——否则,如果e是一个xvalue,decltype(e)T&amp;&amp;,其中Te的类型;

——否则,如果e是左值,decltype(e)T&amp;,其中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&amp;

因此,您的问题的答案很简单:因为规范是这么说的。

【讨论】:

  • 我在这里没有看到对此行为的解释。
  • 谢谢,但我在这里没有看到任何解释,这只是我的问题的复制,我在问他们为什么不同?
  • @HindForsum 午饭后我会尝试从规范中找到相关部分。但你会看到他们说的都是一样的。所以真正的答案将是:因为规范是这么说的!
  • 我认为 @JohannesSchaub-litb 就像 OP 一样,他对此很明确 - 寻找一个 基本原理(毕竟,这是唯一一个表达式周围的括号会改变程序的语义),而不是对程序行为的正式解释。我的看法是,根据用例,程序员希望能够获得文字类型e 有(无括号)或引用。括号用作在语言中表达各自愿望的一种手段,而无需引入新的语法元素或关键字。这是一个拼凑,就像在 C++ 中一样。
  • 人们可能会争辩说,标准中没有回答的问题才是真正有趣的问题;-)。
【解决方案2】:

嗯,我在这里看到的答案是“规范是这样说的”。我查看了 stroustrup 的 decltype 原始草稿,这就是它所说的。

如果 decltype(expr) 中的 expr 是变量或形参 程序员可以追踪变量或参数的声明, decltype 的结果正是声明的类型。如果 expr 是 函数调用,程序员可以手动重载 解决; decltype 的结果是返回类型 最佳匹配函数的原型。的原型 内置运算符由标准定义,如果有的话 缺少,则适用左值具有引用类型的规则。

看看这里的最后一句话,我想这可以解释。由于括号是内置的运算符来表示和表达。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 2013-11-30
    相关资源
    最近更新 更多