Narut Sereewattanawoot
Narut Sereewattanawoot

Reputation: 884

Is it ok to pass function objects by reference?

I have a piece of code that requires passing a function object (functional). I can't use function pointers because I need to store some state variables. Let's say I have quite a few state variables. Is it ok to pass the function object by reference? I've only seen function objects passed by value. This is what my code will look like:

struct FunctionObject {
    double a, b, x, y;
    double operator() (int v, int w) {....}
};

template <class T>
Class MyClass {
     T& func;
     .....
public:
     MyClass(T& func):func(func) {}
     .....
};

Upvotes: 4

Views: 1311

Answers (4)

Antoine
Antoine

Reputation: 14084

It depends mainly on how you intend to instanciate FunctionObject (how you create function objects). If you use references, you must ensure the function object outlives the user (MyClass) object.

For instance:

MyClass* createObject() {
    MyFunction f(...);         // function object created
    return new MyClass(f);     // reference used
                               // function object destroyed => reference invalid
}

is incorrect because the returned object has a reference on a destroyed (invalid) function.

Since you gain very little by passing by reference (avoid copying a small object), it's not worth the hassle (checking objects lifetime) and the risk an oversight (bug)

Upvotes: 1

ecatmur
ecatmur

Reputation: 157414

Passing function objects by reference is fine, but you should be aware that many C++ algorithms copy function objects, so if you need a library algorithm to respect your state you should pass it as a reference inside your function object:

struct State {
    double a, b, x, y;
};
struct Function {
    State &state;
    explicit Function(State &state): state(state) {}
    double operator() (int v, int w) {....}
};
State state;
std::...(..., Function(state), ...)

Also, some library algorithms (e.g. transform) require pre-C++11 that the function object have no side effects i.e. no state whatsoever; this requirement is rarely enforced and is relaxed in C++11.

Upvotes: 7

Pete Becker
Pete Becker

Reputation: 76428

Function objects are objects. You can pass them by reference and you can store references to them, subject to the usual lifetime issues. However, the algorithms in std:: are allowed to make copies of their function objects whenever they like, so any stored state may well be stale, so it may be better to write your function object as a wrapper around a pointer or reference to its state.

Upvotes: 0

0x26res
0x26res

Reputation: 13922

The synthax is correct but...

  • most of the time you're going to call the function object later in your code, so you need to make sure that the reference you've provided in MyClass is still in the scope
  • so in the end since you need to keep the function object in the heap rahter than the stack, you'll have to create a pointer to it... so I recommend using a pointer...

Upvotes: 0

Related Questions