On 02/04/17 02:45 +0300, Ville Voutilainen wrote:
PR libstdc++/79141 * include/bits/stl_pair.h (__wrap_nonesuch): New. (operator=(typename conditional< __and_<is_copy_assignable<_T1>, is_copy_assignable<_T2>>::value, const pair&, const __wrap_nonesuch&>::type)): Change __nonesuch to __wrap_nonesuch. (operator=(typename conditional< __not_<__and_<is_copy_assignable<_T1>, is_copy_assignable<_T2>>>::value, const pair&, const __nonesuch&>::type)): Likewise. (operator=(typename conditional< __and_<is_move_assignable<_T1>, is_move_assignable<_T2>>::value, pair&&, __wrap_nonesuch&&>::type)): Likewise. * testsuite/20_util/pair/79141.cc: New.
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h index 7c7cee2..b746fb4 100644 --- a/libstdc++-v3/include/bits/stl_pair.h +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -179,6 +179,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; + struct __wrap_nonesuch : std::__nonesuch { + explicit __wrap_nonesuch(const __nonesuch&) = delete; + };
Could you please add a comment explaining that this is needed to ensure that functions with parameters of this type are not viable when an argument of {} is used. Because even with such a comment I'll probably not understand this by next week. And I think __explicit_nonesuch or __no_list_init would be a clearer name. We're not really "wrapping" this, unless I misunderstand. OK for trunk, I suppose. This kind of thing is why I want to burn std::pair and std::tuple to the ground.