mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
libstdc++: Make CTAD ignore tuple(const Types&...) constructor [PR121771]
This is similar to the r16-3536-g0bb0d1d2880d56 change for std::pair, so that CTAD ignores the tuple(const Types&...) constructor and only uses the tuple(Types...) -> tuple<Types...> deduction guide. This ensures that the deduced type comes from the decayed argument types. libstdc++-v3/ChangeLog: PR libstdc++/121771 * include/std/tuple (tuple::tuple(const Elements&...)): Use type_identity_t to prevent constructor being used for CTAD. (tuple::tuple(allocator_arg_t, const A&, const Elements&...)): Likewise. * testsuite/20_util/tuple/cons/121771.cc: New test. Reviewed-by: Ville Voutilainen <ville.voutilainen@gmail.com>
This commit is contained in:
committed by
Jonathan Wakely
parent
705d87ba8e
commit
7bafcc3617
@@ -969,7 +969,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
// Defined as a template to work around PR libstdc++/116440.
|
||||
template<typename = void>
|
||||
constexpr explicit(!__convertible<const _Elements&...>())
|
||||
tuple(const _Elements&... __elements)
|
||||
tuple(const type_identity_t<_Elements>&... __elements)
|
||||
noexcept(__nothrow_constructible<const _Elements&...>())
|
||||
requires (__constructible<const _Elements&...>())
|
||||
: _Inherited(__elements...)
|
||||
@@ -1161,7 +1161,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
template<typename _Alloc>
|
||||
constexpr explicit(!__convertible<const _Elements&...>())
|
||||
tuple(allocator_arg_t __tag, const _Alloc& __a,
|
||||
const _Elements&... __elements)
|
||||
const type_identity_t<_Elements>&... __elements)
|
||||
requires (__constructible<const _Elements&...>())
|
||||
: _Inherited(__tag, __a, __elements...)
|
||||
{ }
|
||||
@@ -1470,14 +1470,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
|
||||
_ImplicitCtor<_NotEmpty, const _Elements&...> = true>
|
||||
constexpr
|
||||
tuple(const _Elements&... __elements)
|
||||
tuple(const __type_identity_t<_Elements>&... __elements)
|
||||
noexcept(__nothrow_constructible<const _Elements&...>())
|
||||
: _Inherited(__elements...) { }
|
||||
|
||||
template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
|
||||
_ExplicitCtor<_NotEmpty, const _Elements&...> = false>
|
||||
explicit constexpr
|
||||
tuple(const _Elements&... __elements)
|
||||
tuple(const __type_identity_t<_Elements>&... __elements)
|
||||
noexcept(__nothrow_constructible<const _Elements&...>())
|
||||
: _Inherited(__elements...) { }
|
||||
|
||||
@@ -1562,7 +1562,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_ImplicitCtor<_NotEmpty, const _Elements&...> = true>
|
||||
_GLIBCXX20_CONSTEXPR
|
||||
tuple(allocator_arg_t __tag, const _Alloc& __a,
|
||||
const _Elements&... __elements)
|
||||
const __type_identity_t<_Elements>&... __elements)
|
||||
: _Inherited(__tag, __a, __elements...) { }
|
||||
|
||||
template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
|
||||
@@ -1570,7 +1570,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_GLIBCXX20_CONSTEXPR
|
||||
explicit
|
||||
tuple(allocator_arg_t __tag, const _Alloc& __a,
|
||||
const _Elements&... __elements)
|
||||
const __type_identity_t<_Elements>&... __elements)
|
||||
: _Inherited(__tag, __a, __elements...) { }
|
||||
|
||||
template<typename _Alloc, typename... _UElements,
|
||||
|
||||
45
libstdc++-v3/testsuite/20_util/tuple/cons/121771.cc
Normal file
45
libstdc++-v3/testsuite/20_util/tuple/cons/121771.cc
Normal file
@@ -0,0 +1,45 @@
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
// Bug 121771 - std::tuple CTAD fails for lvalue reference to function type
|
||||
|
||||
#include <tuple>
|
||||
#include <memory>
|
||||
|
||||
void func();
|
||||
|
||||
std::tuple t(func);
|
||||
std::tuple<void (*)()>& r = t;
|
||||
|
||||
struct Explicit {
|
||||
Explicit();
|
||||
explicit Explicit(const Explicit&);
|
||||
} ex;
|
||||
|
||||
std::tuple t2(func, 1);
|
||||
std::tuple<void (*)(), int>& r2 = t2;
|
||||
|
||||
std::tuple t2x(ex, func);
|
||||
std::tuple<Explicit, void (*)()>& r2x = t2x;
|
||||
|
||||
std::tuple t3(1, func, 3);
|
||||
std::tuple<int, void (*)(), int>& r3 = t3;
|
||||
|
||||
std::tuple t3x(ex, 2, func);
|
||||
std::tuple<Explicit, int, void (*)()>& r3x = t3x;
|
||||
|
||||
std::allocator<int> alloc;
|
||||
|
||||
std::tuple ta(std::allocator_arg, alloc, func);
|
||||
std::tuple<void (*)()>& ra = ta;
|
||||
|
||||
std::tuple ta2(std::allocator_arg, alloc, func, 1);
|
||||
std::tuple<void (*)(), int>& ra2 = ta2;
|
||||
|
||||
std::tuple ta2x(std::allocator_arg, alloc, ex, func);
|
||||
std::tuple<Explicit, void (*)()>& ra2x = ta2x;
|
||||
|
||||
std::tuple ta3(std::allocator_arg, alloc, 1, func, 3);
|
||||
std::tuple<int, void (*)(), int>& ra3 = ta3;
|
||||
|
||||
std::tuple ta3x(std::allocator_arg, alloc, ex, 2, func);
|
||||
std::tuple<Explicit, int, void (*)()>& ra3x = ta3x;
|
||||
Reference in New Issue
Block a user