Move semantic with std::function

c++, c++11, standards

Solution

Under 20.8.11.2.1p6, `function(function &&f)` leaves `f` in a valid state with an unspecified value.

The empty state is a valid state, so you should expect that the moved-from function object can be empty.

Because `function` performs type erasure, and function objects can be arbitrarily expensive, the optimisation to leave the moved-from object empty makes sense:

std::function<void()> g{std::bind{f, std::array<int, 1000>{}}};
std::function<void()> h{std::move{g}};

After `h` has been constructed by move from `g`, one would expect the contained `bind` have been transferred from `g` to `h` rather than copying, so `g` would be left empty.

For the following program, gcc 4.5.1 prints `empty`:

#include <functional>
#include <iostream>
void f() {}
int main() {
    std::function<void()> g{f}, h{std::move(g)};
    std::cout << (g ? "not empty\n" : "empty\n");
}

This is not necessarily the most optimal behaviour; inlining small callables (e.g. function pointers) creates a situation where copying the callable is more efficient than moving it and emptying the moved-from object, so another implementation could leave `g` in a non-empty callable state.

Problem

`std::function` provides a constructor from an rvalue ref. What happens to the moved function object by standard? Will it be empty so that calling it again has no effects?

Original source