Brace elision en std:: inicialización de matriz


Supongamos que hay un std::array a inicializar. Está bien si se usan llaves dobles:

std::array<int, 2> x = {{0, 1}};
std::array<int, 2> x{{0, 1}};

También está bien usar llaves individuales en la buena inicialización agregada, ya que la elisión de llaves se encargará de las llaves faltantes:

std::array<int, 2> x = {0, 1};

Sin embargo, ¿está bien usar inicialización de lista con llaves simples? GCC lo acepta, Clang lo rechaza con "no se pueden omitir llaves alrededor de la inicialización del subobjeto cuando se usa la inicialización de lista directa".

std::array<int, 2> x{0, 1};

La única parte de la el estándar donde se menciona la elisión de la abrazadera es 8.5.1 / 12, que dice:

Todas las conversiones de tipo implícitas (Cláusula 4) se consideran al inicializar el miembro aggregate con una expresión de asignación. Si la expresión de asignación puede inicializar un miembro, el miembro se inicializa. De lo contrario, si el miembro es en sí mismo una subagregada, se asume la elisión de llaves y se considera la expresión de asignación para la inicialización del primer miembro de la subagregación.

8.5.1 es sobre la inicialización agregada específicamente, por lo que debería significar Clang es correcto rechazar, ¿verdad? No tan rápido. 8.5.4 / 3 dice:

Lista-inicialización de un objeto o referencia de tipo T se define de la siguiente manera:

[…]

- De lo contrario, si T es un agregado, se realiza la inicialización del agregado (8.5.1).

Creo que significa que exactamente las mismas reglas que con la inicialización agregada, incluida la llave elisión, aplicar, lo que significa que GCC está en lo correcto al aceptar.

Admito que la redacción no es particularmente clara. Entonces, ¿qué compilador es correcto en su tratamiento del tercer fragmento? ¿Ocurre la elisión del corsé en la inicialización de la lista, o no ocurre?

Author: Yakk - Adam Nevraumont, 2013-06-07

2 answers

Se aplica la elisión de llaves, pero no en C++11. En C++14, se aplicarán debido a http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1270 . Si tienes suerte, Clang lo transferirá a su modo C++11 (¡esperemos que lo hagan!).

 20
Author: Johannes Schaub - litb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-07 21:12:09

Pertinente: http://en.cppreference.com/w/cpp/language/aggregate_initialization

En resumen,

struct S {
    int x;
    struct Foo {
        int i;
        int j;
        int a[3];
    } b;
};
S s1 = { 1, { 2, 3, {4, 5, 6} } };
S s2 = { 1, 2, 3, 4, 5, 6}; // same, but with brace elision
S s3{1, {2, 3, {4, 5, 6} } }; // same, using direct-list-initialization syntax
S s4{1, 2, 3, 4, 5, 6}; // error in C++11: brace-elision only allowed with equals sign
                        // okay in C++14
 3
Author: kchoi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-05 23:54:39