web-dev-qa-db-ja.com

複合リテラルは標準C ++ですか?

複合リテラル はC99構造です。私はC++でこれを行うことができますが:

#include <iostream>
using namespace std;

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

たとえば、MSVCはそれをサポートしているようです 拡張機能として 。それでも、私が手に入れることができるすべてのコンパイラーは、上記のコードをコンパイルします。

それでこれはC++ 14で利用可能な機能ですか?別の標準用語はありますか(ブレース初期化を使用して一時的に作成するように見えます)?


サイドノート:「複合リテラル」(または上記と呼ぶべきもの)は パック拡張コンテキスト (言及するだけです)機能)

19
Lorah Attkins

これは、 gccclangの両方がサポートする拡張機能です。 gccドキュメントには次のように書かれています。

拡張機能として、GCCはC90モードとC++で複合リテラルをサポートしますが、セマンティクスはC++では多少異なります。

-pedantic でビルドした場合、警告が表示されます。たとえば、clangは(ライブで参照):

警告:複合リテラルはC99固有の機能です[-Wc99-extensions]

C++のセマンティックの違いは軽微ではなく、C99で明確に定義されるコードは、次の拡張機能を使用してC++で未定義の動作をする可能性があることに注意してください。

C++では、複合リテラルは一時オブジェクトを指定します。一時オブジェクトは、完全な式が終了するまでしか存続しません。その結果、複合リテラルのサブオブジェクトのアドレスを取得する明確に定義されたCコードは、C++では未定義になる可能性があります。

24
Shafik Yaghmour
(float[2]) {2.7, 3.1}

c99複合リテラルです。一部のコンパイラは、拡張機能としてC++でサポートしています。

float[2] {2.7, 3.1}

構文エラーです。

与えられたusing arr = float[2];

arr {2.7, 3.1}

2つのfloatsの一時配列をリスト初期化する有効なC++です。

{2.7, 3.1}

braced-init-listと呼ばれます。

最後に、あなたのコードについては、

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

同様にうまく機能し、完全に有効なC++です。これにより内部でstd::initializer_list<double>が構築されます。本当にfloatsが必要な場合は、数字にfサフィックスを追加します。

24
T.C.