7

A function pointer can point to anything from a free function, a function object, a wrapper over a member function call.

However, the std::bind created functors can have state, as well as custom-created ones. Where that state is allocated, and who is deleting it?

Consider the below example - will the state ( the number 10) be deleted when the vector is deleted? Who know to call a deleter on the functor, and no deleter on the function pointer?

#include <iostream>
#include <functional>
#include <vector>
using namespace std;
using namespace std::placeholders;
class Bar
{
    public:
    void bar(int x, int y) { cout << "bar" << endl; }
};
void foo(int baz){ cout << "foo" << endl; }
int main() {
    typedef std::function<void(int)> Func;

    std::vector<Func> funcs;
    funcs.push_back(&foo); // foo does not have to be deleted
    Bar b;
    // the on-the-fly functor created by bind has to be deleted
    funcs.push_back(std::bind(&Bar::bar, &b, 10, _1)); 

    // bind creates a copy of 10. 
    // That copy does not go into the vector, because it's a vector of pointers.
    // Where does it reside? Who deletes it after funcs is destroyed?

    return 0;
}
Sam
  • 19,708
  • 4
  • 59
  • 82
  • std::bind return you a functor, which hold the copy of values and manage it – Bryan Chen Aug 20 '14 at 11:31
  • 3
    "...because it's a vector of pointers..." No, its a vector of `std::function`. A vector of function pointers would be `std::vector`. – WhozCraig Aug 20 '14 at 11:40
  • 1
    The same problem is already present in the very first line: "A function pointer can point to ... a function object". No, it can't. Function pointers can point to free functions, static methods of classes and non-capturing lambda's. – MSalters Aug 20 '14 at 12:30

2 Answers2

10

std::bind returns an object by value (the object's exact type is an implementation detail of the standard library). This object stores all necessary state and its destructor does all the required cleanup.

Notice that your vector does not store pointers - it stores std::function objects. A std::function object internally stores the object from which it was created (a function pointer or the object returned by std::bind in your case), and its destructor correctly destroys the stored object. Destroying a pointer to function does nothing. Destroying an object of class type invokes its destructor.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • That's a good deal of info, but it does not answer how std::function calls the destructor. Is bind() creating a derived object that's polymorphically deleted? – Sam Aug 20 '14 at 12:38
  • 1
    @sammy: In a word, yes, but no. `std::function` does. It implements the C++ *type erasure* idiom. Look this up. – Laurent LA RIZZA Aug 20 '14 at 12:45
  • Does this mean that if - having a variable of type 'Func' - I reassign this variable with some new 'bind', the previous object is automatically deleted? – Kuba Wyrostek Sep 21 '14 at 18:00
  • @KubaWyrostek The previous object held internally inside the `std::function` object is automatically destroyed, yes. Just like when you assign into a `std::vector`, the objects held in it previously are destroyed. – Angew is no longer proud of SO Sep 21 '14 at 20:02
  • Thanks. Just to clarify: "automatically" here does not mean that it is destroyed by i.e. "going out of scope"? It is intentional action of std::function upon reassignment? – Kuba Wyrostek Sep 21 '14 at 20:04
  • @KubaWyrostek I'd say that's an implementaiton detail of `std::function`, really. It does proper cleanup, that's all you need to know. – Angew is no longer proud of SO Sep 21 '14 at 20:10
2

The std::bind function creates an instance of an unspecified class, and when that object goes out of scope and is destructed, so is the storage for that instance.

Just like instances of any other class with a destructor that releases some resource.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621