This article is about how `std::function`

is implemented and provide some implements that compiled in pre-C++11.

The `std::function`

in C++11 is very fantastic as in a static compiling language like C++ it provides a set of interfaces to wrap any kind of callable objects. A more fantastic fact is that the only C++11 feature that `std::function`

involves is variadic template.

So if we implements a simplified version of `std::function`

with an arbitrary number of template parameters (say, 3 parameters, 1 for the return type and 2 for parameter types), it could be done in pre-C++11 so we don't have to learn the C++11 features right now.

Let us get down to the implements.

### 0. One pointer version

The `std::function`

could be implemented as a `class`

with only one pointer as its only data member, and of course several virtual functions.

The key point is to declare a virtual base class which could be used to wrap any kinds of callable object, like this.

`template <typename Ret, typename Arg0, typename Arg1>`

class function<Ret(Arg0, Arg1)> {

// the virtual base class for callables

struct callable_base {

virtual Ret operator()(Arg0 arg0, Arg1 arg1) = 0;

virtual ~callable_base() {}

};

callable_base* callable_ptr;

public:

Ret operator()(Arg0 arg0, Arg1 arg1)

{

// a call to the function is routed to the member pointer.

return (*callable_ptr)(arg0, arg1);

}

private:

// here is the sub-template-class that inherits callable_base

template <typename F>

struct callable

: callable_base

{

// it can store and make use of any callable object since it is a template class

F functor;

callable(F functor)

: functor(functor)

{}

virtual Ret operator()(Arg0 arg0, Arg1 arg1)

{

return functor(arg0, arg1);

}

};

public:

// so that create a 'function' instance is to specialize the 'callable' template with the type of callable object

template <typename F>

function(F f)

: callable_ptr(new callable<F>(f))

{}

};

The implements above is fine to be instanciated and be called, but apparently there are resource leak problems since there is `new`

in the constructor but no `delete`

in the destructor.

Before we implements the destructor we must be aware of that copy-constructor and copy-assign operator overload shall be implements along with the destructor.

So let's consider about them.

The basic idea to create copy-constructor is to copy each members recursively. However the problem we have here is we don't know how to copy an abstract base pointer. To solve this, we can add a "copy-constructor" as a virtual function and implement it in the subclass.

`template <typename Ret, typename Arg0, typename Arg1>`

class function<Ret(Arg0, Arg1)> {

// ...

struct callable_base {

virtual Ret operator()(Arg0 arg0, Arg1 arg1) = 0;

// add a clone virtual function

virtual callable_base* clone() const = 0;

virtual ~callable_base() {}

};

template <typename F>

struct callable

: callable_base

{

F functor;

// ...

// subclass implements it to make a copy of itself

virtual callable_base* clone() const

{

return new callable<F>(functor);

}

};

callable_base* callable_ptr;

public:

// use clone to copy a function object

function(function const& rhs)

: callable_ptr(rhs.callable_ptr->clone())

{}

function& operator=(function const& rhs)

{

delete callable_ptr;

callable_ptr = rhs.callable_ptr->clone();

}

// and delete the pointer when destructed

~function()

{

delete callable_ptr;

}

This is a oversimplification though it could run. The real world implements (like the implement shipped with gcc) uses more tricks to avoid heap allocation in some situation. Let me explain it in the next post.