复合文字是标准C ++吗?

时间:2015-01-23 18:33:48

标签: c++ c++14 compound-literals

Compound Literals是C99构造。即使我可以用C ++做到这一点:

#include <iostream>
using namespace std;

int main() {
    for (auto i : (float[2]) {2.7, 3.1}) cout << i << endl;
}

似乎MSVC支持它as an extension。然而,我可以得到所有编译器,编译上面提到的代码。

所以这是C ++ 14中提供的功能吗?是否有一个不同的标准术语(我认为只是创建一个临时使用支撑初始化)?


旁注:“复合文字”(或我应该称之为的任何内容)是pack expansion context(仅提及功能)

2 个答案:

答案 0 :(得分:24)

这是gccclang都支持的扩展程序。 gcc文件说:

  

作为扩展,GCC支持C90模式和C ++中的复合文字,尽管语义在C ++中有所不同。

如果您使用-pedantic构建,则会收到警告,例如clang说( see it live ):

  

警告:复合文字是C99特有的功能[-Wc99-extensions]

请注意,C ++中的语义差异并不小,C99中定义良好的代码在C ++中可能具有此扩展名的未定义行为:

  

在C ++中,复合文字指定一个临时对象   直到它的完整表达结束。因此,定义明确   获取复合文字的子对象的地址的C代码可以   在C ++中未定义。

答案 1 :(得分:22)

(float[2]) {2.7, 3.1}

是C99复合文字。一些编译器在C ++中支持它作为扩展。

float[2] {2.7, 3.1}

是语法错误。

给定using arr = float[2];

arr {2.7, 3.1}

是有效的C ++,它列出初始化两个float的临时数组。

{2.7, 3.1}

称为 braced-init-list

最后,对于您的代码,

for (auto i : {2.7, 3.1}) cout << i << endl;

同样有效并且是完全有效的C ++ - 这构建了一个std::initializer_list<double>。如果您真的需要float s,请将f后缀添加到数字中。