Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retaining functors as variables

Tags:

c++

functor

I'm working on a resource management class and want to have the user provide a functor to a "ReleaseResource" method as part of the resource manager's constructor. From there when a resource is requested that functor will be provided as the deleter for the shared_ptr that I will be returning so that the appropriate method will be called when the resource is no longer used.

The problem I'm running into that this requires me to store the functor in my class, and I'm not entirely sure how to do that. Typically when using a functor you template the function like so:

template<class MyFunctor> MyMethod(MyFunctor f) {
    f();
}

Which is great if you intend to use the functor in the scope of that function, but since the template goes out of scope with the function I'm not sure how you would specify a variable of the appropriate type to store the functor for later use.

Can anyone point me in the right direction here?

like image 411
Toji Avatar asked Jan 23 '09 20:01

Toji


People also ask

What is the point of functors?

A functor (or function object) is a C++ class that acts like a function. Functors are called using the same old function call syntax. To create a functor, we create a object that overloads the operator().

What are functors in C++?

A C++ functor (function object) is a class or struct object that can be called like a function. It overloads the function-call operator () and allows us to use an object like a function.

Are functions objects in C++?

A function object is any object for which the function call operator is defined. C++ provides many built-in function objects as well as support for creation and manipulation of new function objects.


1 Answers

template<class MyFunctor> MyMethod(MyFunctor f) {
    boost::function<void()> g = f;
    g();
}

The type you pass to boost::function is the function type. For example, int(bool, char) is the type of a function returning int and taking a bool and a char. That said, if you want to construct the shared_ptr right away, you don't need to store the functor somewhere (boost::function requires the new operator for that, even though for very small functors, it will use special tricks to only use stack allocation (small buffer optimization)):

template<class MyFunctor> MyMethod(MyFunctor f) {
    boost::shared_ptr<T> ptr(new T, f);
}

boost::function is part of tr1 and will be part of the next official C++ Standard. Example:

struct Manager {
    template<typename Deleter>
    Manager(Deleter d) 
        :deleter(d) {

    }

    boost::shared_ptr<Resource> allocate() {
        ...
        return boost::shared_ptr<Resource>(resource, deleter);
    }

private:
    boost::function<void(Resource *)> deleter;
};
like image 180
Johannes Schaub - litb Avatar answered Oct 04 '22 03:10

Johannes Schaub - litb