gpt4 book ai didi

c++ - Clang vs GCC vs MSVC - 使用大括号括起来的初始化列表来创建用户定义的类型?

转载 作者:太空狗 更新时间:2023-10-29 23:50:52 26 4
gpt4 key购买 nike

正在尝试用大括号括起来的初始化列表,编译器的行为似乎有所不同(好吧,这是一个相当新的功能),但想知道正确的行为应该是什么,尤其是如果下面提到的“c3”实际上应该用私有(private)编译,默认初始化变量?

int main() {
struct c1 {
bool b;
char c;
int i;
};

auto c1_ = c1{true, '0', 0};
//clang-3.6 - okay
//gcc-4.9 - okay
//vs-2013 - okay

// ------------------------------------------

struct c2 {
bool b;
char c;
int i = 0; // with default value
};

auto c2_ = c2{true, '0', 0};
//clang-3.6 - okay
//gcc-4.9 - error: no matching function for call to ‘c2::c2(<brace-enclosed initializer list>)’
//vs-2013 - error C2440: '<function-style-cast>' : cannot convert from 'initializer-list' to 'c2'

auto c2__ = c2{true, '0'};
//clang-3.6 - okay
//gcc-4.9 - error: no matching function for call to ‘c2::c2(<brace-enclosed initializer list>)’
//vs-2013 - error C2440: '<function-style-cast>' : cannot convert from 'initializer-list' to 'c2'

// ------------------------------------------

struct c3 {
bool b;
char c;
private:
int i = 0; // with private default value
};

auto c3_ = c3{true, '0'};
//clang-3.6 - error: no matching constructor for initialization of 'c3'
//gcc-4.9 - error: no matching function for call to ‘c3::c3(<brace-enclosed initializer list>)’
//vs-2013 - error C2440: '<function-style-cast>' : cannot convert from 'initializer-list' to 'c3'
}

最佳答案

这是聚合初始化。

定义聚合的 C++11 段落说(n3337,§8.5.1/1):

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

这意味着 c2 不是聚合并且 auto c2_ = c2{true, '0', 0}; 应该在 C++11 中触发诊断( gcc 是正确的)。

但是,使用 clang,您似乎可以在 C++14 模式下编译,这消除了“无大括号或等式初始化器”限制(n3690,§8.5.1/1):

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

因此,auto c2_ = c2{true, '0', 0}; 在 C++14 中是可以的。

关于 auto c2__ = c2{true, '0'};,§8.5.1/7 (n3690) 说:

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 its brace-or-equal-initializer or, if there is no brace-or-equal-initializer, from an empty initializer list (8.5.4).

这意味着可以,clang 可以在 C++14 模式下编译它。

c3 在 C++11 和 C++14 中都不是聚合(因为私有(private)成员),因此所有编译器拒绝它都是正确的。

关于c++ - Clang vs GCC vs MSVC - 使用大括号括起来的初始化列表来创建用户定义的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26193718/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com