2011-11-19 12 views
46

Si no me equivoco, debería ser posible crear un std: array de estas maneras:std :: matriz con inicialización enumera

std::array<std::string, 2> strings = { "a", "b" }; 
std::array<std::string, 2> strings({ "a", "b" }); 

Y, sin embargo, usando GCC 4.6.1 Soy incapaz de conseguir cualquiera de estos para trabajar. El compilador simplemente dice:

expected primary-expression before ',' token 

y, sin embargo, las listas de inicialización funcionan bien con std :: vector. Entonces, ¿cuál es? ¿Me equivoco al pensar que std :: array debería aceptar listas de inicialización, o tiene el equipo GNU Standard C++ Library equivocado?

+0

That crashed clang ... – Dani

+0

No estoy seguro de si esto debería funcionar (no estoy al tanto de 0x cosas) pero, error o no, creo que es porque estás usando 'std: : string' con cadenas literales. ¿Has intentado envolver los literales de cadena con 'std :: string()'? –

+0

@Chris: Esto funciona para mí con gcc 4.6.1 en Mac OSX 10.6. ¿Qué opciones de compilador estás usando? – juanchopanza

Respuesta

72

std::array es gracioso. Se define básicamente así:

template<typename T, int size> 
struct std::array 
{ 
    T a[size]; 
}; 

Es una estructura que contiene una matriz. No tiene un constructor que tome una lista de inicializadores. Pero std::array es un agregado según las reglas de C++ 11 y, por lo tanto, se puede crear mediante la inicialización agregada. Para agregar inicializar la matriz dentro la estructura, es necesario un segundo juego de llaves:

std::array<std::string, 2> strings = {{ "a", "b" }}; 

Tenga en cuenta que la norma sugiere que los apoyos adicionales se pueden elided en este caso. Entonces es probable que sea un error de GCC.

+0

¿El comité estándar hizo esto a propósito? – Dani

+0

¿Por qué el estándar solo requiere que 'std :: array' tenga un constructor que funcione con las listas de inicializadores? –

+6

@PaulManta: Porque entonces no calificaría para la inicialización agregada. La inicialización agregada se puede plegar en tiempo de compilación, dependiendo del tipo de elementos de la matriz (std :: string no califica). La inicialización de la lista del inicializador * debe * ser una llamada a la función de tiempo de ejecución, independientemente del tipo de elementos de la matriz. –

9

Para añadir a la respuesta aceptada:

std::array<char, 2> a1{'a', 'b'}; 
std::array<char, 2> a2 = {'a', 'b'}; 
std::array<char, 2> a3{{'a', 'b'}}; 
std::array<char, 2> a4 = {{'a', 'b'}}; 

todo el trabajo en GCC 4.6.3 (Xubuntu 12.01). Sin embargo,

void f(std::array<char, 2> a) 
{ 
} 

//f({'a', 'b'}); //doesn't compile 
f({{'a', 'b'}}); 

lo anterior requiere doble llaves para compilar. La versión con los apoyos individuales da como resultado el siguiente error:

../src/main.cc: In function ‘int main(int, char**)’: 
../src/main.cc:23:17: error: could not convert ‘{'a', 'b'}’ from ‘<brace-enclosed initializer list>’ to ‘std::array<char, 2ul>’ 

No estoy seguro de qué aspecto de la inferencia de tipos/conversión hace que las cosas funcionan de esta manera, o si se trata de un capricho de la aplicación de GCC.

Cuestiones relacionadas