[PATCH] RFC: remove std::tuple<T, U> partial specialization

Jonathan Wakely jwakely@redhat.com
Fri Aug 17 19:29:00 GMT 2018


While fixing PR 86963 I realised we can get rid of the 2-tuple partial
specialization, and just add the relevant constructors and assignment
operators to the primary template. They're all constrained anyway, so
they won't be available except when sizeof...(_Elements) == 2.

This patch also removes the recursive evaluation of exception
specifications on the assignment operators and tuple::swap members,
just defining them on std::tuple without depending on the base
classes.

BUT it causes:

FAIL: 20_util/tuple/cons/allocator_with_any.cc execution test
/home/jwakely/src/gcc/gcc/libstdc++-v3/testsuite/20_util/tuple/cons/allocator_with_any.cc:35: void test01(): Assertion 'std::get<0>(t).empty()' failed.

where that test does:

    std::tuple<any, any> t(std::allocator_arg,
			   std::allocator<any>{});
    VERIFY(std::get<0>(t).empty());
    VERIFY(std::get<1>(t).empty());

That's because the partial specialization had a special case for
allocator_arg_t:

-      template<typename _U1, typename _U2, typename
-        enable_if<_TMC::template
-                    _MoveConstructibleTuple<_U1, _U2>()
-                  && _TMC::template
-                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
-                 && !is_same<typename decay<_U1>::type,
-                             allocator_arg_t>::value,
-       bool>::type = true>
-        constexpr tuple(_U1&& __a1, _U2&& __a2)
-       : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }

That was added by https://gcc.gnu.org/ml/libstdc++/2016-12/msg00122.html
but I see no justification for that in the standard (and neither
libc++ nor MSFTL does anything special here, so they fail the test
too).

Ville, I'm no longer convinced by your rationale. Why is that
constraint on the 2-tuple partial specialization when the standard
doesn't say anything like "if sizeof...(Types)==2 this constructor
shall not participate in overload resolution unless decay_t<U_i> is
not allocator_arg_t" for the tuple(_UTypes&&...) constructor?

As far as I can tell, the standard says that the test is wrong.

If we think the test is right, we should report a defect. Either way,
I think this patch would be a nice simplification. We can either fix
(or just remove) the test, or constrain the primary template.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 23341 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20180817/056e8caf/attachment.bin>


More information about the Libstdc++ mailing list