[英]what is the difference between aggregate and list initialization
I'm trying to understand the difference between aggregate and list initialization.我试图了解聚合和列表初始化之间的区别。 In particular it's mentioned here that aggregate initialization allows narrowing but that does not seem to be the case特别是这里提到聚合初始化允许缩小但情况似乎并非如此
#include <type_traits>
struct A {
int y;
};
static_assert(std::is_aggregate_v<A>);
int main() {
A a{10.0};
}
Error:错误:
<source>: In function 'int main()':
<source>:10:9: error: narrowing conversion of '1.0e+1' from 'double' to 'int' [-Wnarrowing]
10 | A a{10.0};
| ^~~~
ASM generation compiler returned: 1
<source>: In function 'int main()':
<source>:10:9: error: narrowing conversion of '1.0e+1' from 'double' to 'int' [-Wnarrowing]
10 | A a{10.0};
| ^~~~
Execution build compiler returned: 1
To answer your question very briefly.非常简短地回答你的问题。
I believe the author of the blog was talking about pre-C++11 standards.我相信该博客的作者在谈论 C++11 之前的标准。 Until C++11 the narrowing conversions were possible, however they are now prohibited.在 C++11 之前,收缩转换是可能的,但现在它们被禁止了。
If you are compiling with g++, remove the #include
and static_assert
and run it with the -std=c++03
compile flag and the code will work (but should throw a warning).如果您使用 g++ 进行编译,请删除#include
和static_assert
并使用-std=c++03
编译标志运行它,代码将运行(但应该发出警告)。 As of c++11 and above narrowing conversion is forbidden.从 c++11 及更高版本开始,缩小转换是被禁止的。
You can read more about aggregate initialization here:您可以在此处阅读有关聚合初始化的更多信息:
https://en.cppreference.com/w/cpp/language/aggregate_initialization https://en.cppreference.com/w/cpp/language/aggregate_initialization
Hope it helps: :)希望能帮助到你: :)
The other answer is correct about the concrete behavior of the program you are showing, however to answer the question in your title directly:另一个答案对于您所展示的程序的具体行为是正确的,但是要直接回答标题中的问题:
List-initialization is any initialization with an initializer of the form {/*...*/}
or = {/*...*/}
.列表初始化是使用{/*...*/}
或= {/*...*/}
形式的初始化程序的任何初始化。
(At least before C++20) Aggregate initialization is a specific kind of list-initialization which is used if the type that is being initialized is an an aggregate type (ie an array or a class without user-declared (*not exactly before C++20) constructors, only public
non-static data members and no virtual functions). (至少在 C++20 之前)聚合初始化是一种特定类型的列表初始化,如果正在初始化的类型是聚合类型(即数组或没有用户声明的类(*不完全是之前C++20)构造函数,只有public
非静态数据成员,没有虚函数)。 It is special to other forms of initialization, because it doesn't call a constructor and instead initializes subobjects of the aggregate one-by-one from the list of initializers in the braces.它对于其他形式的初始化是特殊的,因为它不调用构造函数,而是从大括号中的初始化器列表中逐一初始化聚合的子对象。
Since C++20 there is also an an alternative form of aggregate initialization which uses parentheses, so that the above is maybe not exactly true anymore.自 C++20 以来,还有一种使用括号的聚合初始化的替代形式,因此上述内容可能不再完全正确。
The rule that narrowing conversions are forbidden applies to all list-initialization, not specifically to aggregate initialization.禁止缩小转换的规则适用于所有列表初始化,而不是专门用于聚合初始化。 And it doesn't apply to aggregate initialization with parentheses either.它也不适用于带括号的聚合初始化。
All of this applies only since C++11.所有这些仅适用于 C++11。 Before C++11 the only possible initialization with braces was aggregate initialization and narrowing was not forbidden.在 C++11 之前,唯一可能的大括号初始化是聚合初始化,并且不禁止缩小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.