【问题标题】:Is there a more maintainable way to initialize structs?是否有更易于维护的方式来初始化结构?
【发布时间】:2019-08-29 19:12:29
【问题描述】:

假设你有一个这样的结构:

struct Foo {
   int a;
};

目前我正在这样初始化它:

Foo foo = {1};

现在,如果我添加另一个成员:

struct Foo {
   int a;
   int b;
}

代码仍然可以编译,编译器认为初始化完全没问题。但是我希望编译器在向结构添加新成员时产生错误。有可能吗?

【问题讨论】:

  • 您需要保留Foo 的聚合吗?
  • @NathanOliver Ehhm,抱歉,聚合是什么意思?我学习 c++ 才 3 天...
  • 在 C++ 中,structclass 几乎是一回事。有什么理由不使用构造函数?当构造函数的签名发生更改时,编译器将针对所有未更改的用途抛出您想要的错误。
  • 基本上它意味着像你所拥有的类。一个没有任何构造函数的。
  • @Romen 是的,我知道构造函数,但我不想添加它们。我想要的只是添加一个成员并查看错误,没有构造函数(您还必须维护)。

标签: c++ struct initialization


【解决方案1】:

您正在使用aggregate initialization,其行为内置于语言中,无法更改。聚合初始化将允许您保留一些未初始化的成员。但是,您可以使用-Wmissing-field-initializers 告诉 GCC 和 Clang 发出警告。您也可以使用-Werror=missing-field-initializers 将其转化为错误。

您还可以禁止语言本身内的聚合初始化,方法是使您的类不是聚合,而是强制用户使用您声明的构造函数:

struct Foo {
   int a;
   int b;
   Foo(int a, int b) : a(a), b(b) {}
};

现在Foo foo = {1}; 将无法编译,因为聚合初始化不适用于此处,并且构造函数没有足够的参数。

但是,请记住,如果您声明的构造函数未能初始化所有成员,例如,您会意外地写出这样的内容:

struct Foo {
   int a;
   int b;
   Foo(int a, int b) : a(a) {}
};

那么你又会遇到问题。但也可以让编译器警告你。

【讨论】:

  • /Wall /WX 对于 MSVC 来说应该是一个相当挑剔的模式。我不确定即使int main() {} 会通过:-) Details here
  • 天哪。看起来很吓人:example @ godbolt 我认为你应该从/W4 /WX 开始。这似乎效果更好:another example
  • @TedLyngmo ewwww。让我想起了当我尝试禁用 MSVC 的语言扩展时(比如将临时绑定到非常量引用)。这不怎么样。无法再编译它自己的内部头文件了。
  • @alterigel 我并不感到惊讶 :-) 公平地说,MS 建议将/W4 用于新项目,但我想知道谁使用/Wall?大概有人不使用任何标准标题...
  • @TedLyngmo Lol,我打算从 W1 到 Wall 逐步尝试它们,但你已经完成了这项工作,也感谢 goldbolt 网站!不知道
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-02
  • 1970-01-01
  • 2017-02-24
  • 2016-08-26
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多