pointers to member functions with move semantics

Viewed 211

When you have a pointer to a non-static member function of an object on the stack, what exactly happens when the object changes its location because of an move? Does the pointer still point to the location of the moved-from object and thus is invalid/dangling?

3 Answers

Pointers to member functions do not hold a reference to any instance of the class. This is true even for pointers to non-static member functions.

Such a pointer can be constructed without having an instance of the class:

class star {
public:
    void shine();
};

void (star::* smile)() = &sun::shine;

And an instance needs to be specified when calling it:

star sun;

(sun.*smile)();
std::memfn(smile)(sun);

An object does not "change its location". When a move occurs, the state of the object being moved from gets transferred, using some unspecified mechanism (controlled by the object's move constructor or move assignment operator), to the object that gets moved to. The object being moved from continues to exist normally, in some valid but unspecified state.

A simple example would be std::vector. The classical implementation of move semantics for a std::vector involves swapping the internal pointer and size of the contents of the vector. The moved-from vector, at the end of the process, is a valid std::vector with the contents of the moved-to vector (with the moved-to vector having the contents of the moved-from vector).

If you have a pointer to a moved-from object, that pointer still points to the object, in some valid but unspecified state. This remains the case until the object what was moved from gets actually destroyed. In case of an object in automatic scope, that occurs when it normally occurs, when the execution thread leaves the scope with the automatic object. When that happens, you are left with a dangling pointer, no different from any other situation that leaves you with a dangling pointer to an object that no longer exists.

When you have a pointer to a non-static member function of an object on the stack,

You can not have a pointer to a particular object's member functions. The following is invalid and will not compile:

struct obj {
  void f();
};
void func()
{
    obj o;
    using func_ptr = void (obj::*)();
    f_ptr pointer_to_o_f = &o::f; // Error
}
Related