Apparently std::function::operator=(F &&f)
is required to behave exactly as std::function(std::forward<F>(f)).swap(*this);
.
Unless I'm missing something, this definition causes some superfluous moving:
#include <functional>
#include <iostream>
struct A
{
A() {std::cout << "A()\n";}
A(const A &) {std::cout << "A(const A &)\n";}
A(A &&) {std::cout << "A(A &&)\n";}
A &operator=(const A &) {std::cout << "A &operator=(const A &)\n"; return *this;}
A &operator=(A &&) {std::cout << "A &operator=(A &&)\n"; return *this;}
~A() {std::cout << "~A()\n";}
void operator()() const {}
};
int main()
{
std::function<void()> f;
f = A{};
}
Prints:
A() // Created by `A{}` A(A &&) // Moved into temporary `std::function`, but what's the point? A(A &&) // Moved into `f` ~A() ~A() ~A()
(tested on GCC 7.2 and Clang 3.8)
Question: Why can't we eliminate one move, by copying/moving (depending on value category) directly into LHS storage?
Edit: I'm not asking why the move is not optimized away, but rather why it's made in the first place.