【问题标题】:braced-init-list and unsigned types大括号初始化列表和无符号类型
【发布时间】:2021-11-25 07:01:07
【问题描述】:

gcc 8 和 clang 7 不接受以下代码,它们应该默认构造一个 unsigned int 类型的临时代码:

unsigned int ui = unsigned int{};

clang 7报错如

<source>:6:22: error: expected primary-expression before 'unsigned'

Visual C++ 2015 和 2017 接受这一点。

显然,这适用于 int 等类型或任何默认可构造的类类型。

这是正确的 C++14 代码吗(在这种情况下是 clang 和 gcc 的错误)?如果不是,为什么不呢?除了无符号类型,还有哪些类型会受到同样的限制?

【问题讨论】:

  • 试试(unsigned int){};。想想 {} 仅应用于 int,然后有 unsigned 挂在不应该出现的位置,因此出现错误消息。
  • @DeiDei 是标准 C++ 中的语法错误(括号中的 typename 后跟 { 不匹配任何语法规则)

标签: c++ initialization c++14 language-lawyer


【解决方案1】:

“Int”在“unsigned int”中是可选的。

简单尝试:

unsigned ui = unsigned{};

它有效。

编辑: 我找到了这个答案: Standard behavior for direct initialization of unsigned short

只是因为只能使用单字类型名称 函数转换表达式,而 unsigned short 不是一个单词 类型名称;短是。

【讨论】:

  • 感谢您的建议,但我的问题不是如何修复表达式,而是它是否正确。
【解决方案2】:

new_type { expression-list(optional) } like unsigned int{} 符合 explicit type conversion 的语法,它只允许单字类型名称。

后跟花括号初始化列表的单字类型名称是指定类型的纯右值 designating a temporary (until C++17) whose result object is (since C++17) 使用指定的花括号初始化列表初始化的直接列表。

请注意,unsigned int 不是单字类型名称,而 int 是。所以int {} 工作正常。

函数转换表达式也是如此

函数转换表达式由简单类型说明符或 typedef 说明符组成(换句话说,单字类型名称:unsigned int(expression)int*(expression) 无效),

作为一种解决方法,您可以应用类型别名,例如

using type = unsigned int;
type ui = type{};

【讨论】:

  • 谢谢。显然,它不是一个词,我不知道这个限制。
  • @user2019765 我同意这不容易注意到;即使你意识到这一点也很明显。
  • 有趣的是,添加括号适用于 clang,但不适用于 Visual C++,它会产生错误 C4576:带括号的类型后跟初始化列表是非标准的显式类型转换语法
  • @user2019765 我不确定,但我认为接受unsigned int{} 和拒绝(unsigned int){} 都不符合标准。
  • (unsigned int){} 不是 C 样式转换:C 样式转换的形式为 (type)expression,而 {} 不是表达式。使用-pedantic,g++ 警告ISO C++ forbids compound-literals 和clang 警告compound literals are a C99-specific feature
猜你喜欢
  • 2016-12-11
  • 2015-06-04
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 2018-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多