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, eg
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. My question is, why is std::pair
designed to be so special?
I do know why these behaviors occur ...
Nope - in your example you're invoking std::vector::vector(std::initializer_list)
and std::set::set(std::initializer_list)
. Unfortunately std::initializer_list<T>
is basically sugar over a const T[]
array - this means that you cannot move from an initializer_list
.
std::any a{std::move(dnm)};
compiles fine - live example on wandbox.org .
why
std::pair
is designed to be so special?
It's not. It just happens to have both these constructors:
constexpr pair( const T1& x, const T2& y ); // (0)
template <typename U1, typename U2>
constexpr pair( U1&& x, U2&& y ); // (1)
According to cppreference , these constructors are SFINAE-friendly (ie they will not participate in overload resolution if the construction is invalid) .
When invoking
std::pair<int, Do_not_move> p(0, std::move(dnm));
first we try to use (1) , which is invalid. It gets SFINAE'd out, so that (0) remains. That one is fine as T&&
binds to const T&
, and it performs a copy.
If I had to guess why std::pair
has both these constructors: the class was available before forwarding references were invented and it only exposed (0) . When forwarding references were introduced into the language, (1) was added to std::pair
. Probably in order to preserve backwards-compatibility, the constructors were designed to be SFINAE-friendly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.