【问题标题】:Why isn't alignas() taking a parameter pack?为什么 alignas() 不采用参数包?
【发布时间】:2019-09-06 12:59:34
【问题描述】:

根据cppreference.com


对齐说明符(C++11 起)

指定类型或对象的对齐要求。

语法

alignas( 表达式 )
alignas( type-id )
alignas( 包 ... )

  1. alignas(expression) 必须是一个整数常量表达式,其计算结果为零,或者是对齐或扩展对齐的有效值。

  2. 相当于alignas(alignof(type))

  3. 等效于应用于同一声明的多个 alignas 说明符,一个用于参数包的每个成员,可以是类型或非类型参数包。


那么为什么以下内容不适用于 g++、clang 或 VC++?

struct alignas(1, 4) A {};

struct alignas(int, double) A {};

这是缺陷吗?

罢工>

编辑

显然这适用于 g++ 8.2 而不适用于 clang++ 8.0 或 VC++ 19.20.27508.1 所以似乎是一个缺陷,编译器还没有赶上。

编辑

显然,在 cygwin bash shell 中运行 MinGW 的 g++ 编译器会导致奇怪的行为。在 MinGW 的 bash shell 中运行时工作正常。所以,不,这在 g++ 8.2 下也不起作用。

【问题讨论】:

  • GCC 8.2 seems to reject 代码。
  • @Fureeish,不适合我。在我的家用电脑上运行良好。
  • 你能分享你的编译标志吗?和确切的代码?能不能粘贴到godbolt上,选择相同的编译选项,指定结果是否一样?
  • 很奇怪。我使用的唯一参数(除了文件名)是-std=c++17,文件只包含struct alignas(1,4) A {}; struct alignas(int, double) B {};
  • Godbold,它给出了与其他错误相同的错误。在我家的电脑上,没有消息。当然,它也不会生成可执行文件。一定是安装有问题?

标签: c++ c++11 visual-c++ g++ clang++


【解决方案1】:

1, 4int, double 不是参数包。这将是在此上下文中使用的参数包的示例:

template <class... T>
struct Widget
{
  struct alignas(T...) A {};
};

请注意,可以将多个 alignas 说明符应用于同一个声明,因此您的示例可以分别写为 alignas(1) alignas(4)alignas(int) alignas(double)

【讨论】:

  • 嗯,令人困惑的是为什么他们会引入特定的 alignas(pack...) 语法而不添加对 alignas(type-id, ...)alignas(expression, ...) 的可变参数支持 - 这是我能想到的唯一这样的语法选择。一方面,我们已经有了sizeof...(pack)(尽管这与sizeof(pack)... 非常不同),所以alignas...(pack) 会明确区分。如果我们已经添加了这样的语法特殊大小写,我认为alignas(T)... 也不会特别令人困惑。我想这是一些“这对解析器来说更容易”的原因?
  • 哦,好吧,我最初的想法是这样做template &lt;typename Base, typename...Deriveds&gt; struct alignas(T, Us...) {};,我认为这是正确的,但考虑到这也不是参数包,那么是的。这很烦人。
  • @Adrian 但是那个是可行的template &lt;/*as before*/&gt; struct alignas(T) alignas(U...) {};
  • @Adrian 恕我直言,这与 C++ 的其余部分非常不一致。可变参数模板背后的基本思想是,您可以将参数包扩展为逗号分隔的列表,如果您自己在那里编写了这样的列表,那么这样做会形成有效的语法结构。使用参数包的名称而不扩展它意味着您正在对参数包本身而不是它的内容做一些事情。因此,alignas(Ts) 必须被解读为“基于Ts 的对齐方式对齐”。参数包没有对齐,所以这没有意义……
  • sizeof... 是一种单独的 sizeof 表达式,适用于参数包本身(这就是为什么 ... 出现在参数包之前而不是之后,就像它们在包扩展中那样)。对齐不是参数包所具有的属性。因此alignas...(Ts) 在语义上与sizeof...(Ts) 所做的不一致。如上所述,我认为简单地定义 alignas(A, B, C)alignas(1, 2, 4) 指定列表中给出的选项中最强的对齐是有意义的。那么alignas(Ts...) 将与“正常”语法一致……
猜你喜欢
  • 2023-01-04
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 2023-03-08
相关资源
最近更新 更多