jeudi 4 janvier 2018

Why does `std::pair` allow to initialize from an rvalue of class type with a user-defined deleted move constructor?

Consider the following class:

struct Do_not_move {
    Do_not_move() = default;
    Do_not_move(const Do_not_move&) = default;
    Do_not_move(Do_not_move&&) = delete;
private:
    int dummy;
};

From here I learn that std::pair (as well as std::tuple) allows to initialize from an Do_not_move rvalue, e.g.

Do_not_move dnm;
std::pair<int, Do_not_move> p(0, std::move(dnm)); // work well

However, many other STL classes reject such use. For example,

Do_not_move dnm;
std::vector<Do_not_move> v{std::move(dnm)}; // error
std::set<Do_not_move> s{std::move(dnm)};    // error
std::any a{std::move(dnm)};                 // error

I do know why these behaviors occur (in short, the forwarding constructor of std::pair is disabled in such case while those of other STL classes are not). My question is, why std::pair is designed to be so special?

Aucun commentaire:

Enregistrer un commentaire