2010-08-06 9 views
10

Supongamos que tenemos la siguiente función:¿podemos pasar arreglos como argumentos a las funciones mediante esta sintaxis, en los próximos estándares de C++ 0x?

void someFunction(int * araye){ 
for (int i=0;i<5;i++) 
    cout <<araye[i]<<' '; 
cout <<'\n'; 
} 

podemos pasar una matriz a esta función mediante la siguiente sintaxis, bajo los estándares próxima C++ 0x? :

someFunction({1,2,3,4,5}); 

si eso es cierto, habrá que incluso será capaz de utilizar esta sintaxis en cualquier caso en el cual, elementos de la matriz son de tipo POD, como a continuación:

class Test{ 
int adad1; 
int adad2; 
}; 
void someFunction(Test * araye){ 
for (int i=0;i<3;i++) 
    cout <<araye[i].adad1<<'-'<<araye[i].adad2<<' '; 
cout <<'\n'; 
} 
someFunction({{1,2},{3,4},{5,6}}); 

Editar-> después de lo que la gente dijo:
Así que ustedes están diciendo que la expresión entre llaves se tratará básicamente como una initializer_list y proponen usar una función adicional que saca un puntero de esa initializer_list y la pasa a la función prevista, pero este método parece me gusta un truco para poder usar mi en función tendida con esa expresión como argumento, dicho esto, creo que no debería usar esa expresión como argumento en absoluto, cuando mi parámetro de función previsto es un único puntero, o podría haber otro enfoque para usar esa expresión? .

+0

Eso sería bueno, tratar las matrices 'int' como las matrices' char' han sido para siempre ... –

Respuesta

4

Si su función toma const int*, en lugar de int*, entonces sólo tiene una pequeña función de trampolín para tirar el puntero fuera de la std::initializer_list<int> que produce el initialiser aparato ortopédico. Algo como esto (probablemente, no tengo un compilador de C++ 0x para probar con)

void someFunction(const int * array){ 
    for (int i=0; i<5; i++) 
     std::cout << array[i] << ' '; 
    std::cout << '\n'; 
} 

void someFunction(const std::initializer_list<int>& init) { 
    someFunction(init.begin()); 
} 

someFunction({1,2,3,4,5}); 

Si su función necesita saber el final o el tamaño de la matriz (que normalmente será el caso), luego pase init.end() o init.size() como segundo argumento.

+0

Compila y se ejecuta como se esperaba con g ++ 4.4.4, después de cambiar 'initializer' a' initializer_list' – Cubbi

+0

@Cubbi: oh sí. Arreglado. –

2

Wikipedia parece sugerir que puede hacer esto pero solo declarando que la función toma un std::initializer_list<int> como argumento.

+0

sí, pero eso es diferente de un solo puntero. – Pooria

+0

@Pooria: Dependiendo de la implementación, puede o no serlo. Una implementación es libre de tratar 'initializer_list ' básicamente como le plazca, dentro de los límites del cumplimiento de las normas. Podría ser simplemente una matriz en el área de datos estáticos, y el método 'begin()' podría simplemente devolver un 'const T *'. –

+0

@Jon: de acuerdo con el estándar de borrador C++ 0x, 'begin()' * does * simplemente devuelve un 'const T *'. –

4

El tipo de la expresión {1,2,3,4,5} es std::initializer_list<int>. Es un objeto que tiene funciones miembro size(), begin(), end(), pero sin operator[] (por 18.9/1 del C++ 0x FCD)

Si su función se std :: vector o cualquier otro contenedor estándar, esto funcionaría porque los contenedores pueden construirse a partir initializer_lists (todos ellos proporcionan constructores no explícitos que los llevan):

void someFunction(std::vector<int> araye) 
{ 
     for (int i=0;i<5;i++) 
        std::cout << araye[i] <<' '; 
     std::cout <<'\n'; 
} 
int main() 
{ 
     someFunction({1,2,3,4,5}); 
} 

Si usted quiere tener una función que toma un puntero, que tendrá que convertir de alguna manera manual un initializer_list en algo que se puede acceder de tal manera:

void someFunction(int* araye) 
{ 
     for (int i=0;i<5;i++) 
        std::cout << araye[i] <<' '; 
     std::cout <<'\n'; 
} 
void someFunction(std::vector<int> v) 
{ 
     someFunction(&v[0]); 
} 
int main() 
{ 
     someFunction({1,2,3,4,5}); 
} 
+0

Podría ser más eficiente si 'mueve' la 'initializer_list'. –

+0

@Jon: ¿Puedes ampliar esto? – sbi

+1

@sbi: No importa, vea los comentarios sobre @ la respuesta de David. Usted puede simplemente escribir 'someFunction (std :: initializer_list v) {someFunction (v.begin()); } 'en su lugar, lo que evita copiar' initializer_list' en el 'vector'. –

Cuestiones relacionadas