【问题标题】:LAMBDA error: conditional expression of type 'void' is illegalLAMBDA 错误:“void”类型的条件表达式是非法的
【发布时间】:2014-12-23 13:09:19
【问题描述】:

我是编程新手,我正在尝试查看这本 C++ Premier Plus 书籍,但是在检查 LAMBDA 部分时,我在 VBS 2013 上遇到了编译错误

    // use captured variables
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
const long Size = 390000L;


int main()
{
    using std::cout;
    std::vector<int> numbers(Size);
std::srand(std::time(0));
std::generate(numbers.begin(), numbers.end(), std::rand);
cout << "Sample size = " << Size << '\n';

// using lambdas
/*int count3 = std::count_if(numbers.begin(), numbers.end(),
    [](int x){return x % 3 == 0; });
cout << "Count of number divisible by 3: " << count3 << '\n';*/

int count13 = 0;
std::count_if(numbers.begin(), numbers.end(),
    [&count13](int x){count13 += x % 13 == 0; });
cout << "count of number divisible by 13: " << count13 << '\n';

// using a single lambda
/*int count3 = 0;
int count13 = 0;
std::for_each(numbers.begin(), numbers.end(),
    [&](int x){count3 += x % 3 == 0; count13 += x % 13 == 0; });
cout << "Count of number divisible by 3: " << count3 << '\n';
cout << "Count of number divisible by 13: " << count13 << '\n';


  */
    return 0;

}

未注释的部分是我得到的:“void”类型的条件表达式是非法的。我认为编译器正在尝试将 lambda 表达式closurert{body} 作为条件运算符 Exp1 读取? Exp2 : Exp3;.

这个练习的想法是,当使用 2+ lambda 或 1 个联合 lambda 时,它应该返回相同的值输出,而在我的情况下它不会。

感谢您的启迪......

【问题讨论】:

  • 您忘记了 lambda 中的 return 语句。为了清楚起见,您可能需要包含一些括号。
  • 如果你使用count_if,你应该输入计数元素的条件作为第三个参数,如果你想在捕获的变量中计算它们,也许你需要for_each
  • 感谢 Borgleader,只是没注意到...

标签: c++ lambda


【解决方案1】:

如果您没有在 lambda 表达式中使用 return 语句并且没有使用尾随返回类型,则 lambda 评估的返回类型被视为void

代替

int count13 = 0;
std::count_if(numbers.begin(), numbers.end(),
    [&count13](int x){count13 += x % 13 == 0; });

你应该写

int count13 = std::count_if( numbers.begin(), numbers.end(),
                             [](int x ) { return x % 13 == 0; } );

在这种情况下,lambda 的返回类型推断为bool

或者,如果您想使用通过引用捕获的变量来计算可被 13 整除的数字,那么最好使用标准算法 std::for_each 例如

int count13 = 0;
std::for_each( numbers.begin(), numbers.end(),
               [&count13]( int x ) { count13 += x % 13 == 0; } );

在这种情况下,它相当于基于范围的for语句

int count13 = 0;
for ( int x : numbers ) count13 += x % 13 == 0;

【讨论】:

  • 谢谢弗拉德,我想念返回类型。但是为什么在没有返回类型的情况下工作呢? code[&](int x){count3 += x % 3 == 0; count13 += x % 13 == 0; });code 并在使用 2 个 lambda 或 1 个组合时给我不同的输出?样本量 = 390000 可被 3 整除的数:130086 可被 13 整除的数:29792 样本量 = 390000 可被 3 整除的数:129858 可被 13 整除的数:29801
  • @maurux 如果您指的是 std::for_each 算法,那么它的 lambda 表达式的返回类型为 void,因为算法中未使用 lambda 的返回类型。您正在增加 lambda 表达式中捕获的变量 count13。
  • @maurux 你已经改变了你原来的评论,以至于我不明白你想问什么。:)
  • 是的,很抱歉。但我确实理解你。我的最后一点/问题是:这个练习的想法是,当对 count3、count13 或 1 个联合 lambda 用于 count3 和 count13 时,应该为 count3= 130086 和 count13 = 29792 返回相同的值输出,这在我的情况并非如此。使用 2 个 lambda 给我的输出与使用 1 个 lambda 不同
  • @maurux 无论您是使用两个 count_if 算法还是一个 std::for_each 用于两个计数器,结果都应相同。
猜你喜欢
  • 2014-07-26
  • 2017-05-27
  • 2016-07-18
  • 1970-01-01
  • 2018-10-09
  • 2017-11-16
  • 2023-03-12
  • 2014-11-05
  • 2021-11-01
相关资源
最近更新 更多