c++ c++14 compound-literals

¿Los literales compuestos son C++ estándar?



c++14 compound-literals (2)

Los compuestos literales son una construcción C99. Aunque puedo hacer esto en C ++:

#include <iostream> using namespace std; int main() { for (auto i : (float[2]) {2.7, 3.1}) cout << i << endl; }

Parece que, por ejemplo, MSVC lo admite como una extensión . Sin embargo, todos los compiladores que puedo tener en mis manos, compilan el código mencionado anteriormente.

Entonces, ¿ es esta una característica disponible en C ++ 14 ? ¿Existe un término estándar diferente (me parece que solo creo un temporal usando la inicialización con llaves)?

Nota al margen: "Compound Literals" (o como sea que llame a lo anterior) son un contexto de expansión de paquete (solo por mencionar una funcionalidad)


Esta es una extensión que admite gcc y clang . El documento de gcc dice:

Como extensión, GCC admite literales compuestos en modo C90 y en C ++, aunque la semántica es algo diferente en C ++.

si construye con -pedantic , debería recibir una advertencia, por ejemplo, clang dice ( -pedantic en vivo ):

advertencia: los literales compuestos son una característica específica de C99 [-Wc99-extensions]

Tenga en cuenta que las diferencias semánticas en C ++ no son menores y el código que estaría bien definido en C99 puede tener un comportamiento indefinido en C ++ con esta extensión:

En C ++, un literal compuesto designa un objeto temporal, que solo vive hasta el final de su expresión completa. Como resultado, el código C bien definido que toma la dirección de un subobjeto de un literal compuesto puede estar indefinido en C ++.


(float[2]) {2.7, 3.1}

es un literal compuesto C99. Algunos compiladores lo admiten en C ++ como una extensión.

float[2] {2.7, 3.1}

es un error de sintaxis

Dado using arr = float[2]; ,

arr {2.7, 3.1}

es un C ++ válido que inicializa en una lista una matriz temporal de dos float .

{2.7, 3.1}

se llama una lista de inicialización arriostrada .

Finalmente, para tu código,

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

funciona igual de bien y es perfectamente válido C ++ - esto construye un std::initializer_list<double> debajo del capó. Si realmente quiere float s, agregue el sufijo f a los números.