C++ lambda表达式无法编译

4

我正在尝试使用lambda表达式在循环中通过cin输入循环索引的值:

#include<iostream>
using namespace std;

int main(){
  for(int a, ([](int & b){cin>>b;})(a); a < 2; ++a);
  return 0;
}

在Ubuntu上使用g++ 4.5编译时,出现以下错误:

forLoopAndCinTest.c++: In function ‘int main()’:
forLoopAndCinTest.c++:5:14: error: expected unqualified-id before ‘[’ token
forLoopAndCinTest.c++:5:14: error: expected ‘)’ before ‘[’ token
forLoopAndCinTest.c++:5:34: error: expected primary-expression before ‘)’ token
forLoopAndCinTest.c++:5:34: error: expected ‘;’ before ‘)’ token
forLoopAndCinTest.c++:5:40: error: name lookup of ‘a’ changed for ISO ‘for’ scoping
forLoopAndCinTest.c++:5:40: note: (if you use ‘-fpermissive’ G++ will accept your code)
forLoopAndCinTest.c++:5:50: error: expected ‘;’ before ‘)’ token

如果我使用普通函数而不是lambda函数,程序可以编译通过。
使用-fpermissive也没有帮助。
有什么想法吗?


1
当前的C++标准不支持lambda表达式,所以您是否指定了启用C++0x支持的选项? - user180247
是的,Steve。编译时我确实使用了-std=C++0x标志。此外,如果不使用该标志,g++会发出警告。 - badmaash
我认为你不应该在()中捕获变量,而应该使用[]来捕获变量。()用于向lambda表达式传递参数。 - badmaash
3个回答

5

这不是for循环的工作方式。您试图在编译器期望您声明一个int的地方调用一个lambda函数:

for( int a, int2, ...; a < 2; ++a );

现在,

如果我使用普通的函数而不是lambda函数,则程序将编译成功。

是的,但它可能不会做你认为它会做的事情。

void f(int& b)
{
    cin >> b;
}

// ...
for( int a, f(a); a < 2; ++a );

这里,循环声明了两个int变量,分别命名为af。与您预期的不同,循环没有调用f()函数。

请尝试以下方法:

for( int a; cin >> a && a < 2; ++a );

我不明白循环如何将a和f视为变量,也不理解为什么f()没有被调用。如果f()没有被调用,那么cin语句是如何执行的呢?感谢您上次提供的成语。 - badmaash
1
明白了。它根本不执行函数,只是声明一个具有适当类型的变量。 - badmaash
顺便说一下,我得到了我想要的:for(int a, x = (cin >> a && 1); a < 10; ++a)。虽然必须使用额外的变量和&&操作符,但它可以在for循环内部扫描变量。不过很酷。 :) - badmaash

2

for 的第一部分被解释为一个声明。当用 (几乎) 等效的代码替换您的代码时,我们得到完全相同的错误:

int main(){
    int a, ([](int & b){cin>>b;})(a); // This produces the same error
    for(; a < 2; ++a);
    return 0;
}

为了回答你的评论,for (int a, foo(); ...是可行的,但不像你想象的那样。实际上,它声明了一个函数(在for作用域内),返回一个int类型的值,并命名为foo。例如:
int a, foo();

应该这样理解:

int a;
int foo();

所有这些都是为了避免在循环外部使用cin。是的,这肯定会起作用。但我仍然不明白为什么我可以调用声明部分中的任何普通函数,但不包括lambda函数。 - badmaash
你不行。当你写 for (int a, foo() ; a<2 ; a++) 时,你并没有调用 foo 函数。(自己试试看)。 - fouronnes

0

在这之后:for( int a,编译器期望一个名称(变量的名称)-未限定的ID。但在您的情况下,不是这样。


是的,这只是一个表达式列表,所以你的声明应该也能工作。有趣。 - c-smile

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接