Подтвердить что ты не робот

Являются ли составные литералы стандартными С++?

Составные литералы - это конструкция C99. Хотя я могу сделать это в С++:

#include <iostream>
using namespace std;

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

Похоже, что MSVC поддерживает его как расширение. Но все компиляторы, с которыми я могу справиться, составляют вышеприведенный код.

Итак, - это функция, доступная в С++ 14? Есть ли другой стандартный термин (мне кажется, что я просто создаю временную, используя исправленную инициализацию)?


Боковое примечание: "Составные литералы" (или что бы я ни назвал выше) - это контекст расширения пакета (просто чтобы упомянуть функциональность)

4b9b3361

Ответ 1

Это расширение, которое поддерживает gcc и clang. В документе gcc говорится:

В качестве расширения GCC поддерживает сложные литералы в режиме C90 и на С++, хотя семантика несколько отличается в С++.

если вы создаете с помощью -pedantic, вы должны получить предупреждение, например clang говорит (см. его в прямом эфире):

предупреждение: составные литералы являются специфичными для C99 функциями [-Wc99-extensions]

Примечание. Семантические различия в С++ не являются второстепенными, и код, который был бы корректно определен в C99, может иметь поведение undefined в С++ с этим расширением:

В С++ составной литерал обозначает временный объект, который только живет до конца своего полного выражения. В результате четко определенные C-код, который принимает адрес подобъекта сложного литерала, может be undefined в С++.

Ответ 2

(float[2]) {2.7, 3.1}

является литералом C99. Некоторые компиляторы поддерживают его на С++ в качестве расширения.

float[2] {2.7, 3.1}

является синтаксической ошибкой.

Учитывая using arr = float[2];,

arr {2.7, 3.1}

является допустимым С++, который list-инициализирует временный массив из двух float s.

{2.7, 3.1}

называется скобкой-init-list.

Наконец, для вашего кода

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

работает одинаково хорошо и отлично действует С++ - это создает a std::initializer_list<double> под капотом. Если вы действительно хотите float s, добавьте суффикс f к номерам.