为什么我可以从{}初始化一个规则数组,而不是std ::数组 [英] Why can I initialize a regular array from {}, but not a std::array

查看:234
本文介绍了为什么我可以从{}初始化一个规则数组,而不是std ::数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这样做:

  int arr [10] = {}; 

arr 的所有元素都已初始化

为什么不起作用:

  std :: array< int,10> arr({}); 

我从g ++(版本4.8.2)得到以下警告:


警告:成员'std :: array< int,10ul> :: _ M_elems'


缺少初始值设定


解决方案

有两个问题,一个是风格和警告问题。



可能不明显,聚合初始化正在发生在一个临时,然后被用作复制构造函数的参数。这种初始化的更常用的方法如下:

  std :: array< int,10> arr = {}; 

虽然仍然留下警告。



此警告由 gcc错误报告: - -Wmissing-field-initializers relaxation request覆盖和其中一个注释说:


[...]当然,使用C ++语法MyType x = {} ;应支持
,如下所示:



http://en.cppreference.com/w/cpp/language/aggregate_initialization



其中例如:

  struct S {
int a;
float b;
std :: string str;
};

S s = {}; //与S s = {0,0.0,std :: string}相同;

这不应警告先前评论中陈述的原因。


和后续评论说:


初始化不准确(感谢),但
的一般点仍然是:在C中你必须写'= {0}',因为
空大括号初始化器不支持语言(你得到一个
warning with -pedantic);在C ++中,你可以写'= {}'或'T foo =
T();',但你不需要特别写'= {0}'。


最新版本的gcc不会在此情况下产生此警告,看到它现在使用gcc 5.1



我们可以看到这个主题也包含在thead中的Clang Developers列表中: - Wmissing-field-initializers



有关参考草案C ++ 11标准节 8.5.1 [dcl.init.aggr] 说:


如果列表中的initializer-clause比聚合中的
成员少,显式初始化
应从一个空的初始化器列表(8.5.4)初始化。 [
示例:

  struct S {int a; const char * b; int c; }; 
S ss = {1,asdf};

使用asdf初始化ss.a,使用asdf初始化ss.b,
的值表达式int()的表达式,也就是0. -end example]


是有效的C ++,虽然使用 {} 注释是无效的C99。可以认为它只是一个警告,但这似乎是惯用的C + +使用 {} 用于聚合初始化,如果我们使用 -Werror 将警告转为错误。


This works:

int arr[10] = {};

All elements of arr are value-initialized to zero.

Why doesn't this work:

std::array<int, 10> arr({}); 

I get the following warning from g++ (version 4.8.2):

warning: missing initializer for member ‘std::array<int, 10ul>::_M_elems’

解决方案

There are two issues one which is a matter of style and the warning.

Although it may not be obvious, aggregate initialization is happening on a temporary which is then being used as an argument to the copy constructor. The more idiomatic to do this initialization would be as follows:

std::array<int, 10> arr = {}; 

Although this still leaves the warning.

The warning is covered by gcc bug report: - -Wmissing-field-initializers relaxation request and one of the comments says:

[...]Surely, the C++ syntax of saying MyType x = {}; should be supported, as seen here:

http://en.cppreference.com/w/cpp/language/aggregate_initialization

where for instance:

struct S {
  int a;
  float b;
  std::string str;
};

S s = {}; // identical to S s = {0, 0.0, std::string};

That shouldn't warn for the reasons stated in earlier comments.

and a follow-up comment says:

My statement about zero-initialization was inaccurate (thanks), but the general point still stands: in C you have to write ' = {0}' since empty-braces initializer is not supported by the language (you get a warning with -pedantic); in C++, you can write ' = {}' or 'T foo = T();', but you don't need to write ' = {0}' specifically.

The latest versions of gcc does not produce this warning for this case, see it live working with gcc 5.1.

We can see this topic also covered in the Clang Developers lists in the thead: -Wmissing-field-initializers.

For reference the draft C++11 standard section 8.5.1 [dcl.init.aggr] says:

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). [ Example:

struct S { int a; const char* b; int c; };
S ss = { 1, "asdf" };

initializes ss.a with 1, ss.b with "asdf", and ss.c with the value of an expression of the form int(), that is, 0. —end example ]

So as this is valid C++, although as noted using {} is not valid C99. One could argue that it is only a warning, but this seems like idiomatic C++ using {} for aggregate initialization and is problematic if we are using -Werror to turn warnings into errors.

这篇关于为什么我可以从{}初始化一个规则数组,而不是std ::数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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