kits
kits

Reputation: 607

C++ compiler error in count_if algorithm

I am running a simple STL algo to count the number of elements smaller than 50. This program generates the error "called object type 'int' is not a function or function pointer". I've spent the night troubleshooting this, and looking for a similar question on stackoverflow without success, but at this hour I'm getting nowhere. I'd be grateful if someone could point out my error.

#include <iostream>
#include <numeric>
#include <functional>
#include <algorithm>
#include <vector>
#include <cstdlib>

using namespace std;

bool lessThan(double x)    //global function
{
    return (x < 50);
}

int main()
{
    vector<double> v1(5);    //create vector of 5 doubles
    for (auto i : v1) {    //for each element in v1...(auto used to determine type)
        v1[i] = rand() % 100;    //generate random numbers
        cout << v1[i] << endl;
        count_if(v1.begin(), v1.end(), lessThan(v1[i]));
    }

    return 0;
}  

Upvotes: 2

Views: 1853

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 310940

I think you mean the following

for (auto i : v1) {    //for each element in v1...(auto used to determine type)
    v1[i] = rand() % 100;    //generate random numbers
    cout << v1[i] << endl;
}

auto num = count_if(v1.begin(), v1.end(), lessThan );

Also you could use standard functional object std::less declared in header <functional>. For example

#include <functional>
//...

for (auto i : v1) {    //for each element in v1...(auto used to determine type)
    v1[i] = rand() % 100;    //generate random numbers
    cout << v1[i] << endl;
}

auto num = count_if(v1.begin(), v1.end(), std::bind2nd( std::less<double>(), 50.0 ) );

Or you could use a lambda expression

for (auto i : v1) {    //for each element in v1...(auto used to determine type)
    v1[i] = rand() % 100;    //generate random numbers
    cout << v1[i] << endl;
}

auto num = count_if(v1.begin(), v1.end(), []( double x ) { return x < 50.0; } );

Upvotes: 3

Some programmer dude
Some programmer dude

Reputation: 409166

You have two problems: The first about the error you have is because you call the function, but you should only provide a pointer to the function.

The second problem is harder to diagnose, but it's that the range-for statement gives you the values of the container and not the indexes. That means that i will be a double value, and you will get five of those values and each of them will be 0.0.

To solve the last problem I suggest you do something like this instead

for (auto& v : v1)
{
    v = some_value;
}

std::cout << "Number of items whose value is less than 50: "
          << std::count_if(std::begin(v1), std::end(v1), lessThan)
          << '\n';

Upvotes: 5

orlp
orlp

Reputation: 117661

You must pass the predicate function itself to count_if, not the result of a call:

std::count_if(v1.begin(), v1.end(), lessThan);

Upvotes: 4

Related Questions