Assume a following non copyable and non movable struct X with no default constructor and with no single argument constructor:
struct X
{
X(int x, int y) { }
X(const X&) = delete;
X(X&&) = delete;
};
and a vector std::vector<pair<X,X>> v. For inserting into v one could use emplace_back if X was constructible from just one argument, since it effectively calls the constructor of std::pair<X,X>.
We could do something like this:
v.emplace_back(X(42,42),X(69,69));
but in this case a move constructor of X gets called and the latter does not compile. Since this is not possible, we have to make use of the std::piecewise_construct constructor of std::pair and call:
v.emplace_back(std::piecewise_construct, std::forward_as_tuple(42,42), std::forward_as_tuple(69,69));
I would expect this to work properly, but the vector, for some reason, is calling move ctor (or copy, if only move was deleted).
For example changing the container to be std::list, everything works just fine. Adding a < operator to X and creating a std::map<X,X> (which has pairs of X as the nodes) or std::set<std::pair<X,X>> and using emplace instead of emplace_back all seems to work. What is wrong with std::vector?
Full code snippet can be found here.