在阅读了列表初始化及其各种风格之后,我决定测试我正在使用 Xcode 和 Objective-C++ 编写的 openGL ES 应用程序中的一些功能,直到我遇到一些相当晦涩的东西。
我知道(并经常实现)传统的 C 风格结构初始化使用以下语法来初始化 POD,例如 GLKVector2,例如:
GLKVector2 point = { 0,0 }; //copy-initialized
但这种方法可能并不总是程序员的意图。因此,通过删除赋值(和不必要的复制构造操作)以支持直接初始化,人们会假设(从文档中)上述声明如下所示:
GLKVector2 point{ 0,0 }; //direct-initialized, but generates compile error
但是,当代码如下所示时,编译器不会报错:
GLKVector2 point{ { 0,0 } };
对我来说,这似乎是 point
是从内部结构 { 0,0 }
创建的临时文件直接初始化的,因此与第一种方法;临时对象仍然需要分配和释放。
或者这个问题可能只是 GLKit 类型使用的 union/结构布局的性质使编译器感到困惑。
在代码中进一步实现之前,对这种奇怪的语法进行一些澄清,将不胜感激
最佳答案
外括号定义对象本身的初始化器,内括号是对象内部成员的初始化器,例如
GLKVector2 v = { initializers-for-members };
其中 initializers-for-members
是 { 0, 0 }
因为该类型有一个数组成员,由两个元素组成,并且您初始化一个由两个成员组成的数组{a, b}
。
C++ 支持“大括号省略”(8.5.1 [dcl.init.aggr] 第 11 段),这意味着在某些情况下嵌套大括号可以从初始化程序中省略,但在 C++11 中大括号省略只允许用于复制初始化。这就是为什么在复制初始化情况下不需要两组大括号,但在直接初始化情况下却需要它们。
自从 C++11 完成后,规则已更改为 DR 1270在直接列表初始化情况下也允许大括号省略,但这是对后 C++11 草案所做的更改,尚未得到广泛支持。
关于C++11 直接列表初始化语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15122109/