2012-03-08 12 views
18

Sé que puedo hacer esto en C++:C++ cadena de inicialización del campo

string s[] = {"hi", "there"}; 

Pero hay alguna forma de delcare una matriz de esta manera sin delcaring string s[]?

p. Ej.

void foo(string[] strArray){ 
    // some code 
} 

string s[] = {"hi", "there"}; // Works 
foo(s); // Works 

foo(new string[]{"hi", "there"}); // Doesn't work 
+3

¿por qué usaría arreglos de estilo c dinámicamente asignados? Sugeriría que usara 'std :: vector' en su lugar. Al usar C++ 11, puede construirlos usando listas de inicialización, p. 'void foo (vector ); foo ({"hi", "there"}); 'debería funcionar en C++ 11 – Grizzly

Respuesta

18

En C++ 11 puedes. Una nota de antemano: No new la matriz, no hay necesidad de eso.

Primero, string[] strArray es un error de sintaxis, que debe ser string* strArray o string strArray[]. Y supongo que es solo por el ejemplo que no pasa ningún parámetro de tamaño.

#include <string> 

void foo(std::string* strArray, unsigned size){ 
    // do stuff... 
} 

template<class T> 
using alias = T; 

int main(){ 
    foo(alias<std::string[]>{"hi", "there"}, 2); 
} 

Tenga en cuenta que sería mejor si usted no necesita pasar el tamaño de la matriz como un parámetro adicional, y afortunadamente hay una manera: plantillas!

template<unsigned N> 
void foo(int const (&arr)[N]){ 
    // ... 
} 

Tenga en cuenta que esto solo coincidirá con matrices de pila, como int x[5] = .... O temporales, creados por el uso de alias anterior.

int main(){ 
    foo(alias<int[]>{1, 2, 3}); 
} 
4

Con soporte para C++ 11 inicializador lista es muy fácil:

#include <iostream> 
#include <vector> 
#include <string> 
using namespace std; 

using Strings = vector<string>; 

void foo(Strings const& strings) 
{ 
    for(string const& s : strings) { cout << s << endl; } 
} 

auto main() -> int 
{ 
    foo(Strings{ "hi", "there" }); 
} 

falta de que (por ejemplo para Visual C++ 10.0) se pueden hacer cosas como esta:

#include <iostream> 
#include <vector> 
#include <string> 
using namespace std; 

typedef vector<string> Strings; 

void foo(Strings const& strings) 
{ 
    for(auto it = begin(strings); it != end(strings); ++it) 
    { 
     cout << *it << endl; 
    } 
} 

template< class Elem > 
vector<Elem>& r(vector<Elem>&& o) { return o; } 

template< class Elem, class Arg > 
vector<Elem>& operator<<(vector<Elem>& v, Arg const& a) 
{ 
    v.push_back(a); 
    return v; 
} 

int main() 
{ 
    foo(r(Strings()) << "hi" << "there"); 
} 
+1

Demasiado detallado: use un bucle de rango:' for (auto s: cadenas) cout << s << endl; ' – rwst

+0

@rwst: Sí, hoy lo es. Gracias. Probablemente * utilicé iteradores para admitir Visual C++ común en 2012. El bucle simple que muestra tiene una leve ineficacia en que copia cadenas pero (1) eso es insignificante en comparación con el yo en el cuerpo del bucle y (2) de todos modos es irrelevante, ya que no es de lo que se trata este ejemplo, y (3) no es difícil de entender una reescritura de eficiencia (no enseñando malas expresiones idiomáticas). Por lo tanto, a partir de 2015 no veo ninguna razón para mantener el ciclo iterativo que utilicé. No dude en arreglarlo. :) –

+0

@rwst: OK lo actualicé yo mismo. También verifiqué que el ejemplo de Visual C++ 10 compila realmente con VC10. Cuando lo miré ahora, no podía recordar que VC10 admitía referencias rvalue, pero lo hizo (al menos el código se compila y produce el resultado correcto). –

Cuestiones relacionadas