2010-08-06 9 views
10

Supponiamo di avere seguente funzione:possiamo passare gli array come argomenti alle funzioni con questa sintassi, sotto gli imminenti standard C++ 0x?

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

possiamo passare un array a questa funzione dalla seguente sintassi, sotto imminente C++ 0x standard? :

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

se questo è vero, saremo anche in grado di utilizzare questa sintassi, in ogni caso in cui, elementi di matrice sono da tipi POD come di seguito:

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}}); 

Modifica-> dopo quello che la gente ha detto:
Quindi voi ragazzi state dicendo che l'espressione tra parentesi graffe verrà fondamentalmente trattata come una lista_iniziale e propone di utilizzare una funzione extra che estrae un puntatore da quella lista_inizializzazione e lo passa alla funzione desiderata, ma questo metodo sembra mi piace un trucco per poter usare il mio dentro funzione di tesi con quell'espressione come argomento, con quello detto penso che non dovrei usare quell'espressione come argomento, quando il mio parametro funzione è un puntatore singolo, o potrebbe esserci un altro approccio per usare quell'espressione? .

+0

Sarebbe bello, per trattare gli array di 'int' come' gli array di char sono stati per sempre ... –

risposta

4

Se la funzione prende const int*, piuttosto che int*, poi basta una piccola funzione di trampolino di tirare il puntatore fuori dal std::initializer_list<int> che l'initialiser brace produce. Qualcosa di simile (probabilmente, non ho un compilatore C++ 0x per testare 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}); 

Se la funzione ha bisogno di sapere la fine o la dimensione della matrice (che di solito è il caso), quindi passare init.end() o init.size() come secondo argomento.

+0

Compila ed esegue come previsto con g ++ 4.4.4, dopo aver cambiato 'initializer' in' initializer_list' – Cubbi

+0

@Cubbi: oh si. Aggiustato. –

2

Wikipedia sembra suggerire che è possibile farlo ma solo dichiarando la funzione di prendere un argomento std::initializer_list<int>.

+0

sì ma è diverso da un singolo puntatore. – Pooria

+0

@Pooria: a seconda dell'implementazione, potrebbe essere o meno. Un'implementazione è gratuita per il trattamento di 'initializer_list ' in linea di principio, comunque, nel rispetto della conformità agli standard. Potrebbe essere solo una matrice nell'area dei dati statici, e il metodo 'begin()' potrebbe restituire solo un 'const T *'. –

+0

@Jon: secondo lo standard di bozza di C++ 0x, 'begin()' * fa * restituisce semplicemente 'const T *'. –

4

Il tipo di espressione {1,2,3,4,5} è std::initializer_list<int>. Si tratta di un oggetto che ha le funzioni di membro size(), begin(), end(), ma non operator[] (per 18.9/1 del C++ 0x FCD)

Se la funzione ha preso std :: vector o qualsiasi altro contenitore standard, questo dovrebbe funzionare perché contenitori può essere costruito da initializer_lists (tutti forniscono i costruttori non esplicite che li portano):

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}); 
} 

Se si vuole avere una funzione che prende un puntatore, è necessario convertire in qualche modo manualmente un initializer_list in qualcosa che si può accedere in tal modo:

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

Potrebbe essere più efficiente se si 'sposta'' initializer_list'. –

+0

@Jon: puoi approfondire questo? – sbi

+1

@sbi: Non importa, guarda i commenti su @ la risposta di David. Puoi semplicemente scrivere 'someFunction (std :: initializer_list v) {someFunction (v.begin()); } invece, che evita di copiare 'initializer_list' nel' vector'. –

Problemi correlati