【问题标题】:Last minute change in Lambda syntax or gcc bug?Lambda 语法或 gcc 错误的最后一分钟更改?
【发布时间】:2011-12-26 05:59:30
【问题描述】:

我使用 gcc-4.7.0 的 svn 版本来检查一些 C++11 功能,例如Lambda 表达式。几周以来,我的一些旧示例(包括 Lambdas)不再编译。我想知道:

  • 我是否错过了过去几周在 gcc-4.7.0 中实施的 C++11-Lambda-spec 的最后一次更改?
  • 这是 gcc 中的一个错误,它不再识别内联 Lambda 了吗?
  • 还是我误解了 Lambda 语法的其他内容?

有问题的代码似乎涉及直接作为参数提供的内联 Lambda。

你会说下面的代码是正确的 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();
}

如果我更改它并首先将 Lambda 分配给一个变量,它会起作用:

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

我举了一个例子 here ,其中两者都使用 gcc-4.5 编译(除了它引发异常,可能是因为 -pthread 没有链接)。但正如我所说:在我的 gcc-4.7.0-svn 中,第一个变体几周前停止编译。

更新错误信息似乎是解析错误:

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:
           ...

【问题讨论】:

  • 错误是什么?
  • @Vaughn Cato:当然很抱歉。更新...
  • 如果将 lambda 括起来会怎样? ([&img](int c){ 填充(c, img); })
  • 是的! thread th{ ([&amp;img](int c){ fill(c, img); }), red }; 有效。嗯……应该这样吗?
  • @Sam Miller:不完全是。我认为 Std 不需要将 Lambda 放在括号中。

标签: c++ gcc lambda c++11


【解决方案1】:

据我从草案 n3242 中定义的语法可以看出,这段代码是有效的 C++11。一个braced_init-listinitializer-clause的列表组成,可以是assignment-expressions,也可以是braced_init_lists。 assignment-expression 可以是 lambda-expression,这正是您所拥有的第一个元素 ([...](...){...})。

因此,如果认为您可以安全地提交错误报告 :),则不需要用括号将 lambda 括起来。 (当然这个答案是草稿,所以不排除后期改语法的可能性。)

【讨论】:

  • 关于 Lambda,在 N3242 和我能找到的 ISO 版本之间没有变化。
  • 我认为已经“正式”确认 N3242 与委员会的许多成员的 C++11 标准文档逐字相同(除了封面 :))
  • N3242 甚至与 N3290(FDIS,提交批准的最终草案)完全不同。所以我看不出它与最终标准有何相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多