Question

I have a functor like this

struct foo
{
    int a;
    foo(a) : a(a) {}
    int operator()(int b) { return a+b; }
};

And a class like this

class bar
{        
    public:
    foo* my_ftor;
    bar(foo* my_ftor) : my_ftor(my_ftor) {}
    ~bar() {}
};

Then suppose a pointer to this class, which contains a pointer to foo.

foo MyFoo(20);
bar MyBar(&MyFoo);

In a function I pass a reference to bar, and I want to run the functor. I got it working the following way:

void AnyFunction(bar* RefToBar)
{
    int y;
    y = RefToBar->my_ftor->operator()(25);
}

Is there any other "cleaner" way to dereference the functor? Something akin to

y = RefToBar->my_ftor(25);

won't work, sadly...

Any idea? Thank you

Était-ce utile?

La solution

Use real references:

class bar {
public:
  foo &my_ftor;

  bar (foo &f) : my_ftor(f) {}
};


void AnyFunction (bar &reftobar) {
    int y = reftobar.my_ftor(25);
}

And call like this

foo myFoo(20);
bar myBar (myFoo);

AnyFunction (myBar);

In the interest of completeness, here is another answer that is more of a modern approach.

class foo {
public:
    foo (int i) : a(i) {}

    int operator() (int x) const {
        return x + a;
    }
private:
    int a;
};

template <typename F>
void AnyFunction (const F &func) {
    int y = func(25);
}

So you can pass in a foo directly:

AnyFunction (foo (20));

Or another kind of function object, like a lambda:

AnyFunction([](int x) -> int {
    return x + 20;
});

You could also extend bar to include the following function:

int run_foo (int x) const {
    return my_ftor (x);
}

And bind it (#include <functional>):

AnyFunction (std::bind (&bar::run_foo, &myBar, std::placeholders::_1));

Autres conseils

Use std::function they are designed to hold functor of any sort.

#include <functional>
#include <iostream>

struct foo
{
    int _a;
    foo(int a) : _a(a) {}
    int operator()(int b) { return _a+b; }
};


class bar
{        
public:
    std::function<int (int)> _ftor;

    bar(std::function<int (int)> my_ftor) : _ftor(my_ftor) {}
    ~bar() {}
};

void AnyFunction(bar& RefToBar)
{
    int y = RefToBar._ftor(25);
    std::cout << "Y: " << y << std::endl;
}

int AnotherFunction(int b)
{
    return b + 11;
}

int main(int argc, char const *argv[])
{
    foo MyFoo(20);
    bar MyBar(MyFoo);
    bar MyBar_2(AnotherFunction);
    bar MyBar_3([](int b) { return b + 56; });


    AnyFunction(MyBar);
    AnyFunction(MyBar_2);
    AnyFunction(MyBar_3);
    return 0;
}

http://ideone.com/K3QRRV

y = (*RefToBar->my_ftor)(25);

(better use std::function and don't violate demeter)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top