8

I use the svn-version of the gcc-4.7.0 to check out some C++11 features, e.g. Lambda Expressions. Since a couple of weeks some of my old examples including Lambdas to not compile anymore. I wonder:

  • Did I miss a last-minute change in the C++11-Lambda-spec that has been implemented in gcc-4.7.0 in the last weeks?
  • Is it a bug in gcc, that does not recognize inline-Lambdas anymore?
  • Or did I misunderstood something else with Lambda-syntax?

The problematic code seems to involve inline-Lambdas that are provided as arguments directly.

Would you say that the following code is correct C++11 code?

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

If I change it and assign the Lambda to a variable first it works:

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

I put an example here where both compiles with gcc-4.5 (except that it raises an exception, probably because -pthread is not linked). But as I said: In my gcc-4.7.0-svn the first variant stopped compiling a couple of weeks ago.

Update The error message seems to be a parse error:

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
  • 6
    What is the error? Commented Nov 10, 2011 at 14:51
  • @Vaughn Cato: Sorry, of course. update... Commented Nov 10, 2011 at 15:23
  • 5
    What if you parenthesize the lambda? ([&img](int c){ fill(c, img); }) Commented Nov 10, 2011 at 15:27
  • Yes! thread th{ ([&img](int c){ fill(c, img); }), red }; works. Hmmm... Should this be this way? Commented Nov 10, 2011 at 15:42
  • 1
    @Sam Miller: Not quite. I don't think that it is required by the Std to put the Lambda in parenthesis. Commented Nov 10, 2011 at 16:13

1 Answer 1

3

As far as I can tell from the grammar defined in the draft n3242, this code is valid C++11. A braced_init-list is composed of a list of initializer-clause, which can be assignment-expressions or themselves braced_init_lists. An assignment-expression can be a lambda-expression, which is exactly what you have as a first element ([...](...){...}).

Therefore, surrounding the lambda with parentheses should not be required, if think you can safely file a bug report :). (Of course, this answer is based on a draft, so the possibility of a late change in the grammar is not to be excluded.)

Sign up to request clarification or add additional context in comments.

3 Comments

There no changes between N3242 and the ISO version I could find, concerning Lambdas.
I think it has been 'officially' confirmed that the N3242 was word-for-word identical to the C++11 standard document by many members of the committee (apart from the front cover :))
N3242 isn't even word-for-word identical to N3290 (the FDIS, final draft submitted for approval). So I don't see how it's identical to the final standard.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.