2011-11-10 10 views
8

Używam wersji svn z gcc-4.7.0, aby sprawdzić niektóre funkcje C++ 11, np. Wyrażenia Lambda. Od kilku tygodni niektóre z moich starych przykładów, w tym Lambdas, nie są już kompilowane. Zastanawiam się:W ostatniej chwili zmiana składni Lambda lub błędu gcc?

  • Czy brakowało mi ostatniej zmiany w specyfikacji C++ 11-Lambda, która została zaimplementowana w gcc-4.7.0 w ostatnich tygodniach?
  • Czy to błąd w gcc, który nie rozpoznaje już inline-Lambdas?
  • Czy źle zrozumiałem coś innego za pomocą składni Lambda?

Problematyczny kod wydaje się dotyczyć inline-Lambdas, które są dostarczane bezpośrednio jako argumenty.

Czy można powiedzieć, że następujący kod jest prawidłowy kod 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(); 
} 

Jeśli zmienię go i przypisać lambda do zmiennej pierwszy to działa:

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

kładę przykład here gdzie zarówno kompiluje z gcc-4.5 (z wyjątkiem, że zgłasza wyjątek, prawdopodobnie dlatego, że -pthread nie jest połączony). Ale jak już powiedziałem: W moim gcc-4.7.0-svn pierwszy wariant przestał się kompilować kilka tygodni temu.

Aktualizacja Komunikat o błędzie wydaje się być błąd parse:

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

Jaki jest błąd? –

+0

@Vaughn Cato: Przepraszam, oczywiście. aktualizuj ... – towi

+5

Co, jeśli zignorujesz lambdę? ([& img] (int c) {wypełnij (c, img);}) –

Odpowiedz

3

O ile mogę powiedzieć z gramatyki określonymi w projekcie n3242, kod ten jest ważny C++ 11. A braced_init-list składa się z listy initializer-clause, które mogą być s lub same w sobie braced_init_list s. Numer assignment-expression może być lambda-expression, który jest dokładnie tym, co masz jako pierwszy element ([...](...){...}).

Dlatego otaczanie lambda nawiasami nie powinno być wymagane, jeśli uważasz, że możesz bezpiecznie złożyć raport o błędzie :). (Oczywiście, ta odpowiedź jest oparta na szkicu, więc nie można wykluczyć możliwości późnej zmiany gramatyki.)

+0

Nie ma zmian między N3242 a wersją ISO, którą mogłem znaleźć, dotyczącą Lambdas. – towi

+0

Myślę, że "oficjalnie" potwierdzono, że N3242 było słowo w słowo identyczne ze standardowym dokumentem C++ 11 przez wielu członków komitetu (oprócz przedniej okładki :)) – sehe

+0

N3242 to nawet nie słowo -to-słowo identyczne z N3290 (FDIS, ostateczny projekt przedłożony do zatwierdzenia). Nie widzę więc, jak to jest identyczne z ostatecznym standardem. –

Powiązane problemy