2
votes

I'm new to programming and I'm trying to review this C++ premier plus book, however while checking LAMBDA part I get into a compile error on my 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;

}

The uncommented part is the one I get: conditional expression of type 'void' is illegal. I think the compiler is trying to read the lambda expression closurert{body} as conditional operator Exp1 ? Exp2 : Exp3;.

Also the idea of this exercise is that while using 2+ lambdas or 1 joint lambda it should return the same value output, which in my case it doesn't.

Appreciate your enlightenment...

1
You forgot a return statement in the lambda. And you might want to include some parentheses for clarity.Borgleader
if you're using count_if you should input condition for counted elements as a third argument, if you want to count them in captured variable perhaps you need for_each.Predelnik
thanks Borgleader, just didn't notice...maurux

1 Answers

4
votes

If you did not use a return statement in a lambda expression and did not used a trailing return type then the return type of the lambda evaluation is considered as void.

Instead of

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

you should write

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

In this case the return type of the lambda is deduced as bool.

Or if you want to use a variable captured by reference that to count numbers that are divisible by 13 then it is better to use standard algorithm std::for_each For example

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

In this case it is equivalent to the range based for statement

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