【问题标题】:C++14 uniform initialization on structs结构上的 C++14 统一初始化
【发布时间】:2017-07-15 21:30:59
【问题描述】:

我有以下相当简单的代码:

    WNDCLASSEX windowClass = {0};

    windowClass.cbSize { sizeof(WNDCLASSEX) };

我想知道为什么上面的代码不起作用而下面的代码起作用:

    WNDCLASSEX windowClass = {0};

    windowClass.cbSize = { sizeof(WNDCLASSEX) };

Visual Studio 15 2017 给了我这两个错误:

1: 期望一个';'

2:错误 C2064:术语不计算为采用 1 个参数的函数

【问题讨论】:

  • 这是赋值,不是初始化。在 C++ 中,您使用 = 为变量赋值。
  • @Sneftel 混淆了,你也可以用= 来初始化一个。

标签: c++ c++11 visual-c++ c++14 uniform-initialization


【解决方案1】:

您不能多次初始化同一个变量(windowClass),也不能在单独的初始化语句中初始化成员变量。

在你的情况下,因为 cbSize 是第一项

WNDCLASSEX windowsClass { sizeof(WNDCLASSEX) };

这会将 cbSize 设置为 sizeof(WNDCLASSEX) 并将结构的其余部分设置为 0。

【讨论】:

    【解决方案2】:

    第一个版本“不起作用”,因为它在语法上毫无意义。 C++ 语法中没有能够解析您的第一个变体的分支。编译器根本不知道您要通过该字符序列说什么。那么问题来了:您想通过第一个版本实现什么目标?

    第二个版本有效,因为它是有效的 C++ 代码。赋值右侧的{ sizeof(WNDCLASSEX) } 被解释为创建/初始化与windowClass.cbSize 相同类型的临时对象。然后将该临时对象分配给windowClass.cbSize。即,由于 windowClass.cbSize 具有 UINT 类型,因此您的第二个版本被解释为

    windowClass.cbSize = UINT{ sizeof(WNDCLASSEX) };
    

    实际效果与

    windowClass.cbSize = sizeof(WNDCLASSEX);
    

    【讨论】:

      【解决方案3】:

      或者为什么不使用完整的 c++?

      struct WndClasssEx : WNDCLASSEX
      {
          WndClassex() : WNDCLASSEX { sizeof(WNDCLASSEX) } {}
      
      }
      
      auto mywndclass = WndClasssEx();
      DoSomethingWindowsy(&mywndclass);
      

      参见 c++ 标准,[Class] 部分(此处引自标准草案 n4527, 2015)。

      特别是关于标准布局类型的注释:

      [ 注意:标准布局类对于与用其他编程语言编写的代码进行通信很有用。 它们的布局在 9.2 中指定。 ——尾注]

      【讨论】:

      • @AnT 这不是一个把戏,它是完全有效的 c++ 并且被标准明确允许并且格式良好。
      • 是允许的。但是,任何使用此类技巧的人都会很快遇到其局限性。例如。虽然可以使用WndClasssEx * 代替WNDCLASSEX *,但您将无法使用数组或WndClasssEx,其中需要WNDCLASSEX 的数组。您将无法在需要 WNDCLASSEX ** 指针的地方使用 WndClasssEx ** 指针。这个技巧的适用范围非常狭窄,这就是为什么它不值得。
      • @AnT 标准特别允许数组大小写。该技术在整个 WTL 和 ATL 中都使用。现在我不喜欢 Microsoft 编码实践,但在这种情况下它们是正确的。正如你所提到的,有一些限制。这些被通过 c++ 接口确保正确性的能力所抵消。
      • @RichardHodges:AnT 完全正确,标准 C++ 中不允许使用数组大小​​写。 ATL 利用了 Microsoft C++ 编译器的许多特定于实现的行为,这些行为是不可移植的。
      • @BenVoigt 你能引用这个标准吗?我对它的阅读表明我的 MyWndClassEx 结构与基类完全相同,因为它们是 POD。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多