简体   繁体   English

C ++ 11直接列表初始化语法

[英]C++11 direct-list-initialization syntax

After reading up on list-initialization and its various flavours, I decided to test out some features in an openGL ES app I'm writing using Xcode and Objective-C++, until I ran into something rather obscure. 在阅读了列表初始化及其各种风格之后,我决定在我使用Xcode和Objective-C ++编写的openGL ES应用程序中测试一些功能,直到遇到一些晦涩的问题。

I've known about (and frequently implement) the conventional C style structure initialization using the following syntax to initialize POD, such as a GLKVector2, for example: 我已经知道(并经常实现)常规C样式结构的初始化,使用以下语法来初始化POD,例如GLKVector2:

GLKVector2 point = { 0,0 };    //copy-initialized

but this approach may not always be what's intended by the programmer. 但是这种方法可能并不总是程序员想要的。 So, by removing the assignment (and a needless copy construction operation), in favour of direct-initilization, one would assume (from the documentation) the above declaration would appear like so: 因此,通过删除分配(和不必要的副本构建操作),有利于直接初始化,可以(从文档中)假定以上声明看起来像这样:

GLKVector2 point{ 0,0 };    //direct-initialized, but generates compile error

However, the compiler doesn't complain when the code looks like this: 但是,当代码如下所示时,编译器不会抱怨:

GLKVector2 point{ { 0,0 } };

To me, this appears as point is being direct-initialized from a temporary created from the inner structure { 0,0 } and thus not offering any advantage over the first approach; 对我来说,这似乎是从内部结构{ 0,0 }创建的临时目录直接初始化的point ,因此与第一种方法相比没有任何优势。 the temporaries still have to be allocated and deallocated. 临时人员仍然必须分配和释放。

Or perhaps this issue is simply the nature of the union/struct layout used by GLKit types confusing the compiler. 也许这个问题仅仅是GLKit类型使用的并集/结构布局的本质而使编译器感到困惑。

Some clarification on this odd syntax, before further implementation in the code, would be much appreciated 在代码中进一步实施之前,对此奇数语法进行一些澄清将不胜感激

The outer braces delimit the initializer for the object itself, the inner braces are the initializer for a member inside the object, eg 外部括号为对象本身的初始化程序定界,内部括号为对象内部成员的初始化程序,例如

GLKVector2 v = { initializers-for-members };

where initializers-for-members is { 0, 0 } because the type has an array member, of two elements, and you initialize an array of two members with { a, b } . 其中的initializers-for-members{ 0, 0 }因为该类型具有一个包含两个元素的数组成员,并且您使用{ a, b }初始化了一个包含两个成员的数组。

C++ supports "brace elision" (8.5.1 [dcl.init.aggr] paragraph 11) which means nested braces can be left out of the initializer under certain circumstances, but in C++11 brace elision is only allowed for copy-initialization. C ++支持“括号删除”(8.5.1 [dcl.init.aggr]第11段),这意味着在某些情况下可以将嵌套括号排除在初始化程序之外,但是在C ++ 11中,括号省略仅允许进行复制初始化。 。 This is why you don't need two sets of braces for the copy-init case, but do need them for direct-init. 这就是为什么在copy-init情况下不需要两组花括号,而在Direct-init情况下需要它们的原因。

Since C++11 was completed the rules have been changed by DR 1270 to allow brace elision in the direct-list-initialization case too, but that's a change made to the post-C++11 draft and not widely supported yet. 自从C ++ 11完成以来, DR 1270更改了规则,也允许在直接列表初始化的情况下使用大括号删除,但这是对C ++ 11之后的草案所做的更改,尚未得到广泛支持。

According to docs GLKVector2 is: 根据文档 GLKVector2是:

union _GLKVector2
   {
   struct { float x, y; };
   struct { float s, t; };
      float v[2];
};
typedef union _GLKVector2 GLKVector2;

That's why you need double braces, you're initializing by initializing a union member. 这就是为什么需要双括号的原因,您需要通过初始化工会成员来进行初始化。 Member-wise aggregate initialization occurs in-place . 成员级聚合初始化就地发生 If it were a flat structure, your single-braces assumption would work. 如果是扁平结构,则您的单括号假设将起作用。 This also happens when initializing an std::array (eg std::array<int, 2> a{{1, 2}} ) because it's a POD aggregate, and no temporary C arrays are involved. 初始化std::array (例如std::array<int, 2> a{{1, 2}} )时也会发生这种情况std::array<int, 2> a{{1, 2}}因为它是POD聚合,并且不涉及任何临时C数组。

You should look at aggregate initialization . 您应该查看聚合初始化

EDIT 编辑

Actually, looking up the docs, there're rules about brace elision (only allowed in copy-initialization context) that may be of interest. 实际上,在查找文档时,可能会有一些关于花括号省略的规则(仅在复制初始化上下文中允许)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM