【问题标题】:Why can't MSVC and GCC initialize a struct with a field with a default value为什么 MSVC 和 GCC 不能使用具有默认值的字段初始化结构
【发布时间】:2017-05-11 21:53:46
【问题描述】:
int main() {
  struct WorkItem {
    int node;
    unsigned predecessorIndex = 0;
  };  

  auto x = WorkItem { 0 };

  return 0;
}

这段代码可以用 Clang 编译,但不能用 GCC:

source_file.cpp:在函数'int main()'中:

source_file.cpp:9:25: 错误:没有匹配函数调用‘main()::WorkItem::WorkItem()’ 自动 x = 工作项 { 0 }; ^

source_file.cpp:9:25:注意:候选人是:

source_file.cpp:4:10: 注意:main()::WorkItem::WorkItem() 结构工作项 { ^

source_file.cpp:4:10:注意:候选人需要 0 个参数,提供 1 个

source_file.cpp:4:10: 注意:constexpr main()::WorkItem::WorkItem(const main()::WorkItem&)

source_file.cpp:4:10:注意:没有已知的参数 1 从“int”到“const main()::WorkItem&”的转换

source_file.cpp:4:10: 注意:constexpr main()::WorkItem::WorkItem(main()::WorkItem&&)

source_file.cpp:4:10:注意:没有已知的参数 1 从“int”到“main()::WorkItem&&”的转换

或 MSVC:

source_file.cpp(9): 错误 C2440: 'initializing': 无法从 'initializer list' 转换为 'main::WorkItem'

source_file.cpp(9):注意:没有构造函数可以采用源类型,或者构造函数重载决议不明确

从标准的角度来看,Clang 是否错误地编译了此代码,或者 MSVC 和 GCC 是否错误? 另外,为什么删除 = 0 允许 GCC 和 MSVC 编译?例如

int main() {
  struct WorkItem {
    int node;
    unsigned predecessorIndex = 0;
  };  

  auto x = WorkItem { 0 };

  return 0;
}

GCC 版本:4.9.3 Clang 版本:3.7.0 MSVC 版本:19.00.24215.1

【问题讨论】:

  • 显示整个编译命令,包括所有选项。 -std= 选项尤其会影响结果。另外,这是一个非常旧的 g++ 版本。

标签: c++ gcc visual-c++ clang language-lawyer


【解决方案1】:

GCC 版本:4.9.3

使用默认成员初始化器进行聚合初始化是 GCC does not support until GCC 5.x 的 C++14 功能。

MSVC 版本:19.00.23506

我相信这是 VC 2015 的更新 1。使用默认成员初始化器进行聚合初始化是 VC doesn't support until 2017 的 C++14 功能。

【讨论】:

  • 我弄错了 MSVC 版本:19.00.24215.1 是正确的
  • 换句话说,在 C++11 中 WorkItem 不是聚合,但在 C++14 中是。
  • @HBellamy:那是 2015 年更新 3(如果您只列出年份和更新编号会容易得多。使用版本让我不得不去查找它们的含义)。现在还不是 VC 2017,是 VC 实现这个功能的时候。
  • 谢谢!我现在可以在这里确认:docs.microsoft.com/en-gb/cpp/cpp-conformance-improvements-2017
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 2011-01-19
  • 1970-01-01
相关资源
最近更新 更多