2012-11-06 13 views
7

Non so se quello che ho è un bug del compilatore o se semplicemente non conosco la sintassi per quello che sto cercando di fare. Immaginate una funzione che prende 2 riferimenti ad array:Qual è la sintassi dei parametri di riferimento degli array di template variadic?

void takeArrays(const char (&str1)[4], const char (&str2)[4]) { 
} 

Questo compila bene quando viene chiamato con:

takeArrays("foo", "bar"); 

Perché dovrei voler fare questo? Perché passare const char* perde le informazioni sulla dimensione della stringa letterale, e questo è importante per quello che sto facendo.

Quello che voglio veramente fare, tuttavia, è passare un numero variabile di riferimenti di array. Questo è dove le cose diventano leggermente brutte (peggiora). Ho provato questo ingenuamente:

template<typename... Args> 
void takeArrays(const char (&Args... strs)[4]) { 
} 

e ottenuto "error: variable or field ‘takeArrays’ declared void" e "error: expected primary-expression before ‘const’" (GCC 4.6). Così ho provato questo:

template<typename... Args> 
void takeArrays(const char (&(Args... strs))[4]) { 
} 

e ottenuto "no matching function for call to ‘takeArrays(const char [4], const char [4])’" e "candidate is template<class ... Args> void takeArrays(const char (& (*)(Args ...))[4])". Che è illeggibile ma sembra vicino a quello che voglio. Ho provato molte varianti e non riesco a farlo compilare.

Supponendo c'è un modo corretto di scrivere quanto sopra, quello che voglio fare è chiamare:

takeArrays("foo", "foobar", "longerstring"); 

e ottenere un elenco variadic di array di diverse dimensioni, vale a dire la chiamata di cui sopra dovrebbe essere ampliato dalla compilatore:

void takeArrays(const char (&str1)[4], const char (&str2)[7], 
       const char (&str3)[13]); 

che era il primo think ho provato a fare, e il mio tentativo è stato qualcosa di simile:

template<size_t... Sizes> 
void takeArrays(const char (&strs)[Sizes]...); 

Inutile dire che tutto ciò che ho ricevuto erano messaggi di errore. Sono consapevole che quello che sto cercando di fare è un po 'folle ma voglio davvero sapere se è possibile, e in tal caso, qual è la sintassi appropriata. Grazie in anticipo.

risposta

9

La sintassi per array variadic dello stesso tipo di elemento è:

template<size_t... Sizes> 
void takeArrays(const char (&...args)[Sizes]); 

Questo è simile al generale variadic sintassi di riferimento const:

template<typename... Args> 
void takeArrays(const Args &...args); 

Un modo semplice per ricordare è che l'ellissi va immediatamente prima del nome del parametro.

+0

Sì, ha funzionato. Grazie! Ricorderò i puntini di sospensione prima del trucco del nome del parametro. Per curiosità, come scriverei i parametri originali della stessa misura? Ho provato 'template void takeArrays (cont char Args (& ... args ([4])' e 'const char (Args & ... args) [4]' e quelli no lavoro –

+5

@ ÁtilaNeves Non è possibile che funzioni per la stessa ragione per cui non è possibile scrivere un modello di funzione variadica prendendo più 'int's:' modello void foo (int ... i/* non funziona: nessun pacchetto da espandere qui * /); '. La soluzione usuale sarebbe quella di consentire matrici della stessa dimensione con un tipo di elemento diverso, ad esempio' template void foo (T (& ... args) [Dimensione]); '. Puoi quindi aggiungere facoltativamente un' static_assert' per far rispettare che tutti 'T' siano' const char'. –

Problemi correlati