Tamojit Chatterjee
Tamojit Chatterjee

Reputation: 161

The following code does not work

I am using MSVC 2012 and when I compile the program below it says:

The term does not evaluate to a function taking 0 arguments

I am sure that the problem is with the mem_fun and mem_fun_ref function call. Please provide a correct way to call the functions.

#include<iostream>
#include<algorithm>
#include<functional>
#include<string>
#include<vector>
#include<iterator>

using namespace std;

#define PRINT(A, Sp) copy(A.begin(), A.end(), ostream_iterator<decltype(*A.begin())>(cout, Sp))

struct Generate {
    int a;
    Generate(int a) : a(a) {
    }
    Generate gen() {
        return Generate(rand()%100);
    }
    void testing() {
        vector<Generate> a(5), b, c;
        generate(a.begin(), a.end(), mem_fun(&Generate::gen));
        generate_n(back_inserter(b), 5, mem_fun_ref(&Generate::gen));
    }
};

void main() {
    Generate a(32);
    a.testing();
}

Upvotes: 1

Views: 177

Answers (3)

BlackMamba
BlackMamba

Reputation: 10254

    struct Generate {
    int a;
    Generate(int a) : a(a) {
    }
    Generate(){}
    Generate gen() {
        return Generate(rand()%100);
    }
    void testing() {
        vector<Generate> a(5), b, c;
        generate(a.begin(), a.end(), bind(mem_fun(&Generate::gen), this));
        generate_n(back_inserter(b), 5, bind(mem_fun(&Generate::gen), this));
    }
};

I chang the code to this.

Upvotes: 0

juanchopanza
juanchopanza

Reputation: 227370

Something of the form

auto f = mem_fun(&Generate::gen);

generates a function that takes an argument of type Generate:

auto f = mem_fun(&Generate::gen);
Generate g;
auto x = f(g);

whereas std::generate_n requires a functor taking no arguments.

It looks like you need something of the form

std::bind(&Generate::gen, this)

Upvotes: 2

jrok
jrok

Reputation: 55395

The problem is that functor returned by mem_fun will have a operator() that takes 1 argument of type Generate* but the functor used by std::generate should take no parameters.

If gen doesn't need access to class data, you can make it static and get rid of mem_fun altogether:

#include<iostream>
#include<algorithm>
#include<functional>
#include<string>
#include<vector>
#include<iterator>
using namespace std;
#define PRINT(A, Sp) copy(A.begin(), A.end(), ostream_iterator<decltype(*A.begin())>(cout, Sp))
struct Generate {
    int a;
    Generate() {}
    Generate(int a) : a(a) {
    }
    static Generate gen() {
        return Generate(rand()%100);
    }
    void testing() {
        vector<Generate> a(5), b, c;
        generate(a.begin(), a.end(), &Generate::gen);
        generate_n(back_inserter(b), 5, &Generate::gen);
    }
};

int main() {
    Generate a(32);
    a.testing();
}

This compiles fine after I added default constructor and made main return int.

Upvotes: 3

Related Questions