2011-11-10 12 views
8

Io uso la versione svn del gcc-4.7.0 per controllare alcune funzionalità di C++ 11, ad es. Lambda Expressions. Da un paio di settimane alcuni dei miei vecchi esempi incluso Lambdas non sono più compilati. Mi chiedo:Modifica dell'ultimo minuto nella sintassi Lambda o bug di gcc?

  • Ho perso una modifica dell'ultimo minuto nella specifica C++ 11-Lambda che è stata implementata in gcc-4.7.0 nelle ultime settimane?
  • Si tratta di un bug in gcc, che non riconosce più inline-Lambdas?
  • Oppure ho frainteso qualcos'altro con la sintassi Lambda?

Il codice problematico sembra coinvolgere inline-Lambdas forniti direttamente come argomenti.

Diresti che il codice seguente è corretto codice C++ 11?

#include <thread> 
using namespace std; 

struct Image {}; // dummy 

void fill(int color, const Image& image) { 
} // dummy 

int main() { 
    int red; 
    Image img; 
    thread th{ 
     [&img](int c){ fill(c, img); }, // error? 
     red }; 
    th.join(); 
} 

Se cambio e assegno il Lambda a una variabile prima funziona:

#include <thread> 
using namespace std; 

struct Image {}; // dummy 
void fill(int color, const Image& image) { 
} // dummy 

int main() { 
    int red; 
    Image img; 
    auto f = [&img](int c){ fill(c, img); }; // lambda 
    thread th{ f, red };      // ok now 
    th.join(); 
} 

Ho messo un esempio here dove entrambi compila con gcc-4.5 (tranne che solleva un'eccezione, probabilmente perché -pthread non è collegato). Ma come ho detto: nella mia gcc-4.7.0-svn la prima variante ha smesso di compilare un paio di settimane fa.

Aggiornamento Il messaggio di errore sembra essere un errore di analisi:

In function 'int main()': 
...:30:11: error: expected '=' before '(' token 
...:30:12: error: expected primary-expression before 'int' 
...:30:12: error: expected ')' before 'int' 
...:30:36: error: no matching function for call to 
      'std::thread::thread(<brace-enclosed initializer list>)' 
...:30:36: note: candidates are: 
      ... 
+6

Qual è l'errore? –

+0

@Vaughn Cato: Scusa, certo. aggiornamento ... – towi

+5

Cosa succede se si parentesi il lambda? ([& img] (int c) {fill (c, img);}) –

risposta

3

Per quanto posso dire dalla grammatica definita nel progetto di n3242, Questo codice è valido C++ 11. A braced_init-list è composto da un elenco di initializer-clause, che può essere assignment-expression s o se stessi braced_init_list s. Un assignment-expression può essere un lambda-expression, che è esattamente quello che hai come primo elemento ([...](...){...}).

Pertanto, non è necessario che circondi il lambda con le parentesi, se si pensa di poter archiviare in modo sicuro una segnalazione di errore :). (Naturalmente, questa risposta è basata su una bozza, quindi non è da escludere la possibilità di un cambiamento tardivo nella grammatica.)

+0

Non sono state apportate modifiche tra N3242 e la versione ISO che ho trovato, riguardante Lambdas. – towi

+0

Penso che sia stato "ufficialmente" confermato che l'N3242 era identico al documento standard C++ 11 parola per parola da molti membri del comitato (a parte la copertina :)) – sehe

+0

N3242 non è nemmeno una parola -for-word identico a N3290 (il FDIS, progetto finale presentato per approvazione). Quindi non vedo come sia identico allo standard finale. –

Problemi correlati