为什么我的struct的成员不能使用`{}`来正确初始化? [英] Why are my struct's members not properly initialised using `{}`?

查看:99
本文介绍了为什么我的struct的成员不能使用`{}`来正确初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

  #include< iostream& 

struct T
{
int a,b,c;
};

int main()
{
T t = {0};
std :: cout<< t.a < ','<< t.b < ','< t.c < '\\\
';
}

输出

  0,0,0 

经过多年的代码在关键的生产环境中快速运行,提供一个重要的函数,项目的需求改变了,我需要的输出 1,1,1



所以,我改变了 {0} {1}

  #include< iostream& 

struct T
{
int a,b,c;
};

int main()
{
T t = {1};
std :: cout<< t.a < ','< t.b < ','< t.c < '\\\
';
}

输出

  1,0,0 

我希望 1,1,1



解决方案

p>当你写 = {0} 时,只显式初始化第一个成员;其余的都是根据标准隐式初始化的,所以它乍一看乍一看你明确地初始化所有成员与您写的 0

第一成员。所以当有一天,你改变为 1 ,认为它会改变所有成员,你会有一个bug,像这里。



因此,没有附加的解释性评论, = { 0} 不会通过我的团队中的代码审查。您最初应该写成:

  T t = {}; 

现在,根据新的要求来解决你的问题,你应该写:

  T t = {1,1,1}; 

或者,如果你不介意你的 struct 可能丢失POD,给予 T 构造函数。






< h3>正式字词


[C ++ 11:8.5.1 / 2]:当聚集由初始化器列表初始化时,如8.5.4中所指定的,初始化器列表的元素将作为聚合成员的初始化器,以增加下标或成员顺序。每个成员都是从相应的 initializer-clause 初始化的。如果 initializer-clause 是一个表达式,并且需要缩小转换(8.5.4)来转换表达式,则该程序是错误的。 [..]



[C ++ 11:8.5.1 / 6]:如果 initializer-clause 的数量超过要初始化的成员或元素数量,则 initializer-list 错误。



[C ++ 11:8.5.1 / 7]: 如果有更少的 initializer-clause该列表比聚合中的成员有更多的成员,那么未明确初始化的每个成员将从一个空的初始化列表(8.5.4)初始化。



I had the following code:

#include <iostream>

struct T
{
   int a, b, c;
};

int main()
{
   T t = {0};
   std::cout << t.a << ',' << t.b << ',' << t.c << '\n';
}

Output:

0,0,0

After many years of this code running happily in a critical production environment, serving a vital function, the requirements of the project changed and I needed the output to be 1,1,1.

So, I changed {0} to {1}:

#include <iostream>

struct T
{
   int a, b, c;
};

int main()
{
   T t = {1};
   std::cout << t.a << ',' << t.b << ',' << t.c << '\n';
}

Output:

1,0,0

I expected 1,1,1 instead.

Why are my struct's members not all being initialised properly?

解决方案

When you write = {0}, that only explicitly initialises the first member; the rest are zero-initialised implicitly according to the standard, so it appears at first glance that you explicitly initialised all members with the 0 that you wrote, but you didn't.

That place where you wrote 0 only affects the first member. So when, one day, you changed it to 1 thinking that it'll change all members, you'll have a bug, like here. It's misleading/dangerous/silly/fragile code.

For that reason, without an accompanying explanatory comment, = {0} will not pass code review in my team. You should originally have written:

T t = {};

And now, to solve your problem according to the new requirements, you should write:

T t = {1,1,1};

or, if you don't mind your struct potentially losing POD-ness, give T a constructor.


Formal wording

[C++11: 8.5.1/2]: When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause. If the initializer-clause is an expression and a narrowing conversion (8.5.4) is required to convert the expression, the program is ill-formed. [..]

[C++11: 8.5.1/6]: An initializer-list is ill-formed if the number of initializer-clauses exceeds the number of members or elements to initialize.

[C++11: 8.5.1/7]: If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from an empty initializer list (8.5.4).

这篇关于为什么我的struct的成员不能使用`{}`来正确初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆