2015-11-23 12 views
8
#include <iostream> 
using namespace std; 
int print(int i) 
{ 
    cout<<endl<<i; 
} 


template<typename ...Args> 
inline void pass(Args&&...args) 
{ 

} 

template<typename ...args> 
inline void expand(args&&... a) 
{ 
    print(a) ...; //this doesn't expand 
    //pass(print(a)...); this works 

} 
int main() { 



    expand(1,2,3,4); 

    return 0; 
} 

getta errore:parametro non pacchi ampliato con '...'

In function 'void expand(args&& ...)': 
error: expected ';' before '...' token 
    print(a) ...; 
     ^
parameter packs not expanded with '...': 
    print(a) ...; 
      ^

Perché l'uso di questa funzione 'pass' è necessario?

+2

parametro pacco è consentito fondamentalmente in cui è consentito un elenco separato da virgole. Esiste un numero fisso di contesti: elenchi di parametri di funzione, elenchi di parametri del modello, inizializzatori ecc. Un'espressione non è un contesto valido. Un operatore virgola non crea un elenco separato da virgole. –

+0

Se SO chiede di aggiungere ulteriori dettagli, aggiungere ulteriori dettagli. Testo non fittizio Grazie. –

risposta

12

Essenzialmente, l'espansione di un parametro pacco E... produce un elenco E1, E2, [...], EN, uno per ciascun elemento E nella confezione. Questo costrutto sintattico è valido solo in luoghi in cui le liste sono grammaticalmente corrette, come nelle chiamate di funzioni, negli elenchi di inizializzatori, ecc. Un'espressione che contiene più operatori virgola non conta.

Credo che con fold expressions (N4295: Folding expressions (Andrew Sutton, Richard Smith)) sarete in grado di scrivere semplicemente:

(print(a), ...); 

In questa espressione,

  • print(a) è un'espressione con un parametro pacchetto non espanso,
  • , è l'operatore e
  • ... desi gnates l'espansione piega destra.

Il risultato della intera espressione è che (print(a), ...) si trasformerà in

print(a1) , (print(a2), (print(a3), print(a4))) // (assuming four elements). 
+1

ora mi hai fatto chiedere perché questo è il caso, dal momento che 'foo(), foo();' è un'espressione valida. –

+0

@RichardHodges è un'espressione valida, ma non è un * elenco * in base alla grammatica. – TartanLlama

+1

Lo capisco. Quello che mi chiedo è perché l'espansione del pacchetto era limitata agli elenchi e non consentita per le dichiarazioni. –

5

espansioni Pack può avvenire solo in contesti Expansion Pack. Questi sono essenzialmente:

  • controventata inizializzazione
  • elenchi di inizializzazione
  • inizializzazioni aggregati funzione
  • invita
  • inizializzazioni matrice

Di questi il ​​più facile da utilizzare nel caso sarebbe ultimo:

#include <iostream> 
using namespace std; 
int print(int i) 
{ 
    cout<<endl<<i; 
    return 0; 
} 

template<typename ...args> 
inline void expand(args&&... a) 
{ 
    using expander = int[]; 
    (void)expander{0, ((void)print(a), 0)...}; 
} 

int main() 
{ 
    expand(1,2,3,4); 

    return 0; 
} 
espansione

Demo

+0

@LightnessRacesinOrbit Non capisco –

+3

Sto ridendo di C++. Che questa sintassi sia il modo più semplice per fare questa cosa semplice è ridicolo. –

Problemi correlati