C++ 中的***是啥?
Posted
技术标签:
【中文标题】C++ 中的***是啥?【英文标题】:What is top-level in C++?C++ 中的***是什么? 【发布时间】:2021-02-23 18:09:26 【问题描述】:在example 14 under [dcl.init.list]
中,标准在使用列表初始化来描述代码语义时,在缩小转换的范围内使用术语“***”。我不知道这是什么意思。
这段代码执行没有错误:
int f(int a) return 1;
int main()
int a[] = f(2), f(2.0);
int b[] = f(2.0), f(2); // No error because: double-to-int conversion is not at the top-level
我还尝试了以下方法。我认为这与初始化顺序无关:
int f(int a) return 1;
int main()
int a[] = f(2), f(2.0);
int b[] = f(2.0), f(2); // double-to-int conversion is not at the top-level
//int c[] = f(2147483645.0f), f(2); // This is erroring out due to narrowing.
int d[] = f(2), f(2.0); // Now I'm sure top-level doesn't mean the order of initialization.
我想知道什么是***?文档here 和here 没有描述它。
我对这个术语感到好奇的原因是因为我试图了解当隐式调用缩小转换时列表初始化器何时工作。
我也不确定术语。例如,是否存在诸如***类、***类型或***列表初始化器之类的东西?
【问题讨论】:
“没有错误,因为:double-to-int 转换不在顶层” 那么这句话是从哪里来的呢?这是一个警告吗?还有什么?到目前为止,从我们掌握的信息来看,唯一使用它的人就是您;) 请在您的问题中添加关键细节! (但是,标准不是“文档”) @AsteroidsWithWings “此处”链接之一指向标准,其中显示“注意 7:如上所述,列表初始化中的***不允许此类转换。”可以在问题中更清楚地指出,是的 @idclev463035818 我已经修复了它 有时单词只是单词,并没有比从上下文中得到的含义更有意义。是的,可以有一个“***类”,就像你将 3 个盒子叠放在一起就有一个***盒子,每个人都会明白指的是哪个盒子 【参考方案1】:这不是一个严格定义的术语。但是在您链接的[dcl.init.list]/note-7
中,“在顶层”似乎意味着“直接写在花括号列表中,而不是嵌套表达式中”。
所以,在int x[] = 1.0, f(2.0);
中,1.0
位于顶层,因为它直接写在花括号列表中,但2.0
不是因为它嵌套在函数调用表达式中。
【讨论】:
接受这个作为解决方案,因为它清楚地指出int e[] = 2.0;
是列表初始化上下文中的缩小错误。 @Asteroids With Wings ,您的 cmets 帮助制定了想法。但是,我只能接受一个。
@Jerry 您自己引用的标准中的例子已经指出了这一点,但可以肯定;)【参考方案2】:
这不是一个严格定义的 C++ 标准术语。相反,它只是在草率的英语意义上的意思。您可以想象有人使用其他短语,例如“函数的前面”或“相应的头文件”,这些在技术上不是 C++ 术语,但会被广泛理解。
在这种情况下,它们指的是更高级别的嵌套。例如,考虑这个 sn-p:
void foo()
int j[2][2] = 3, 4, 5, 6;
显然4
比3, 4
嵌套更深,而3, 4, 5, 6
嵌套更深。事实上,3, 4, 5, 6
根本没有嵌套。您阅读的文本的作者会将其称为“***”。
另一位作者可能会争辩说foo
处于“顶层”,因此它在一定程度上取决于上下文。在你发布的报价中,意思很清楚。
【讨论】:
并且该标准在讨论这种情况下的某些转换时(note 7)确实以非规范方式简要地使用了这个术语,尽管我实际上看不出double-to-int
在哪里受到约束o.O
“在您发布的报价中,意思很清楚。” 如果“级别”的意思是“嵌套大括号的级别”,您能否举一个缩小范围的示例允许转换,因为它不在顶层?
@HolyBlackCat 好时机 - 请参阅注释 7,这不是您要寻找的规则,但确实总结了它
我可以写这样的东西,而且效果很好:int e = f(2.0);
。 AFAIK,它不是***的(假设会出错吗?)
@Jerry 你可以写int n = 2.0;
。函数调用、数组和嵌套是无关紧要的。【参考方案3】:
这只是一个英文短语,要根据上下文来理解。
[dcl.init.list]
的规则告诉我们列表初始化器中的项目如何不能涉及缩小转换。注释 7 继续提醒我们这一点,使用术语“***”来描述它正在谈论的那些事情(列表的直接“成员”)。
您所指的示例 14 还包括一个示例,其中带有列表初始化的语句恰好包含缩小转换,但注释提醒我们这很好,因为转换发生在“较低级别”的嵌套,再次使用术语“***”来描述在初始化列表中立即列出的实体。不需要对实际列表项应用缩小转换。
“***”一词没有正式的定义;在考虑可能的嵌套时,它应该被解释为英语。
【讨论】:
别忘了,笔记不是规范的。他们的目的是澄清。 @PeteBecker 我知道。因此,它所做的只是“提醒我们”已经给出的规则。 ;) 正如我所说,该术语没有正式的定义(即规范文本中没有任何内容)。【参考方案4】:前段时间我对此感到困惑,但我想我现在已经很好地理解了这个概念。
在我去解释这个概念之前,必须注意的是,不是顶层或低级的对象,而是顶层或低级的“const”取决于它在表达式或上下文中的位置。
*** const 表示(that) "const" 使对象本身成为 const(无论该对象指向什么)。
低级 const 表示(that) "const" 表示被引用(/指向)的对象是 const。
例如
const int i = 10; // const is indicating that i itself is const so it (const) is top level.
const int const *p = &i; // leftmost const is indicating that "pointed to" is const, so that const is low-level, other const in the expr is top-level.
此外,*** const 可以出现在任何 obj 类型(内置类型、类类型、指针类型)中,而低级 const 出现在复合类型的基类型中,例如指针&参考。
在指针中,low-level 和 top-level 都可以出现,但是在 refs 中,consts 总是低级的,因为 refs 隐含地具有 top-level consts(一旦初始化,refs 就不能绑定到其他 objs ,所以从某种意义上说,它们隐含了***常量)。
希望对您有所帮助。
【讨论】:
好的,谢谢。指针间接是对上述答案的进一步补充。上面的讨论解释了嵌套上下文中的顶层。以上是关于C++ 中的***是啥?的主要内容,如果未能解决你的问题,请参考以下文章