Closed
Description
On clang trunk (i.e. 18), I'm getting compile errors for nested construction of tuples with flags -std=c++23 -stdlib=libstdc++
. This in turn causes issues with std::make_obj_using_allocator
. These errors do not occur if instead compiled with -std=c++20
.
For instance, see Godbolt example: https://godbolt.org/z/PPTjbc1s6
The aforementioned example compiles the following:
#include <memory>
#include <string>
using elem_type = std::pair<int, std::pair<int, std::string>>;
void example_0() {
std::make_tuple(std::make_tuple());
}
void example_1() {
std::make_tuple(
std::piecewise_construct, std::make_tuple(),
std::make_tuple(std::piecewise_construct, std::make_tuple(), std::make_tuple(std::allocator<elem_type>{})));
}
void example_2() {
std::make_obj_using_allocator<elem_type>(std::allocator<elem_type>{});
}
and produces the following errors:
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/memory:78:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/unique_ptr.h:36:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:691:2: error: pack expansion contains parameter pack '_UTypes' that has a different length (1 vs. 0) from outer parameter packs
691 | using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
| ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:853:27: note: in instantiation of template type alias '__convertible' requested here
853 | = _TCC<true>::template __convertible<_Args...>::value;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:948:12: note: in instantiation of static data member 'std::tuple<std::tuple<>>::__convertible<>' requested here
948 | explicit(!__convertible<_UElements&...>)
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1991:28: note: while substituting deduced template arguments into function template 'tuple' [with _UElements = <>]
1991 | return __result_type(std::forward<_Elements>(__args)...);
| ^
<source>:7:8: note: in instantiation of function template specialization 'std::make_tuple<std::tuple<>>' requested here
7 | std::make_tuple(std::make_tuple());
| ^
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/memory:78:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/unique_ptr.h:36:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:691:2: error: pack expansion contains parameter pack '_UTypes' that has a different length (3 vs. 1) from outer parameter packs
691 | using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
| ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:853:27: note: in instantiation of template type alias '__convertible' requested here
853 | = _TCC<true>::template __convertible<_Args...>::value;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:948:12: note: in instantiation of static data member 'std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>::__convertible<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>' requested here
948 | explicit(!__convertible<_UElements&...>)
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1040:49: note: while substituting deduced template arguments into function template 'tuple' [with _UElements = <std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>]
1040 | = __bool_constant<__is_constructible(_Tp, _Args...)>;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1046:16: note: in instantiation of template type alias '__is_constructible_impl' requested here
1046 | : public __is_constructible_impl<_Tp, _Args...>
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:161:30: note: in instantiation of template class 'std::is_constructible<std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, const std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>> &>' requested here
161 | __enable_if_t<bool(_Bn::value)>...>;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:177:16: note: (skipping 4 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
177 | : decltype(__detail::__and_fn<_Bn...>(0))
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:768:26: note: in instantiation of function template specialization 'std::_TupleConstraints<true, std::piecewise_construct_t, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>>::__is_implicitly_constructible<const std::piecewise_construct_t &, const std::tuple<> &, const std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>> &>' requested here
768 | _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1021:53: note: in instantiation of template type alias '_ImplicitCtor' requested here
1021 | _ImplicitCtor<_Valid, const _UElements&...> = true>
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1023:2: note: while substituting prior template arguments into non-type template parameter [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, _Valid = true]
1023 | tuple(allocator_arg_t __tag, const _Alloc& __a,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1024 | const tuple<_UElements...>& __in)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1025 | : _Inherited(__tag, __a,
| ~~~~~~~~~~~~~~~~~~~~~~~~
1026 | static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1027 | { }
| ~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1991:14: note: while substituting deduced template arguments into function template 'tuple' [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, _Valid = (no value), $3 = (no value)]
1991 | return __result_type(std::forward<_Elements>(__args)...);
| ^
<source>:11:8: note: in instantiation of function template specialization 'std::make_tuple<const std::piecewise_construct_t &, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>>' requested here
11 | std::make_tuple(
| ^
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/memory:78:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/unique_ptr.h:36:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:691:2: error: pack expansion contains parameter pack '_UTypes' that has a different length (3 vs. 1) from outer parameter packs
691 | using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
| ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:853:27: note: in instantiation of template type alias '__convertible' requested here
853 | = _TCC<true>::template __convertible<_Args...>::value;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:959:12: note: in instantiation of static data member 'std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>::__convertible<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>' requested here
959 | explicit(!__convertible<const _UElements...>)
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1040:49: note: while substituting deduced template arguments into function template 'tuple' [with _UElements = <std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>]
1040 | = __bool_constant<__is_constructible(_Tp, _Args...)>;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1046:16: note: in instantiation of template type alias '__is_constructible_impl' requested here
1046 | : public __is_constructible_impl<_Tp, _Args...>
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:161:30: note: in instantiation of template class 'std::is_constructible<std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, const std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>> &>' requested here
161 | __enable_if_t<bool(_Bn::value)>...>;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:177:16: note: (skipping 4 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
177 | : decltype(__detail::__and_fn<_Bn...>(0))
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:768:26: note: in instantiation of function template specialization 'std::_TupleConstraints<true, std::piecewise_construct_t, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>>::__is_implicitly_constructible<const std::piecewise_construct_t &, const std::tuple<> &, const std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>> &>' requested here
768 | _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1021:53: note: in instantiation of template type alias '_ImplicitCtor' requested here
1021 | _ImplicitCtor<_Valid, const _UElements&...> = true>
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1023:2: note: while substituting prior template arguments into non-type template parameter [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, _Valid = true]
1023 | tuple(allocator_arg_t __tag, const _Alloc& __a,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1024 | const tuple<_UElements...>& __in)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1025 | : _Inherited(__tag, __a,
| ~~~~~~~~~~~~~~~~~~~~~~~~
1026 | static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1027 | { }
| ~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1991:14: note: while substituting deduced template arguments into function template 'tuple' [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, _Valid = (no value), $3 = (no value)]
1991 | return __result_type(std::forward<_Elements>(__args)...);
| ^
<source>:11:8: note: in instantiation of function template specialization 'std::make_tuple<const std::piecewise_construct_t &, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>>' requested here
11 | std::make_tuple(
| ^
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/memory:78:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/unique_ptr.h:36:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:691:2: error: pack expansion contains parameter pack '_UTypes' that has a different length (3 vs. 1) from outer parameter packs
691 | using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
| ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:853:27: note: in instantiation of template type alias '__convertible' requested here
853 | = _TCC<true>::template __convertible<_Args...>::value;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:948:12: note: in instantiation of static data member 'std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>::__convertible<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>' requested here
948 | explicit(!__convertible<_UElements&...>)
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1040:49: note: while substituting deduced template arguments into function template 'tuple' [with _UElements = <const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>]
1040 | = __bool_constant<__is_constructible(_Tp, _Args...)>;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1046:16: note: in instantiation of template type alias '__is_constructible_impl' requested here
1046 | : public __is_constructible_impl<_Tp, _Args...>
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:161:30: note: in instantiation of template class 'std::is_constructible<std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>, const std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &> &>' requested here
161 | __enable_if_t<bool(_Bn::value)>...>;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:177:16: note: (skipping 6 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
177 | : decltype(__detail::__and_fn<_Bn...>(0))
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1023:2: note: while substituting prior template arguments into non-type template parameter [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>, _Valid = true]
1023 | tuple(allocator_arg_t __tag, const _Alloc& __a,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1024 | const tuple<_UElements...>& __in)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1025 | : _Inherited(__tag, __a,
| ~~~~~~~~~~~~~~~~~~~~~~~~
1026 | static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1027 | { }
| ~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1991:14: note: while substituting deduced template arguments into function template 'tuple' [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>, _Valid = (no value), $3 = (no value)]
1991 | return __result_type(std::forward<_Elements>(__args)...);
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/uses_allocator_args.h:147:19: note: in instantiation of function template specialization 'std::make_tuple<const std::piecewise_construct_t &, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>>' requested here
147 | return std::make_tuple(piecewise_construct,
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/uses_allocator_args.h:233:9: note: in instantiation of function template specialization 'std::uses_allocator_construction_args<std::pair<int, std::pair<int, std::basic_string<char>>>, std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>' requested here
233 | std::uses_allocator_construction_args<_Tp>(__a,
| ^
<source>:17:8: note: in instantiation of function template specialization 'std::make_obj_using_allocator<std::pair<int, std::pair<int, std::basic_string<char>>>, std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>' requested here
17 | std::make_obj_using_allocator<elem_type>(std::allocator<elem_type>{});
| ^
4 errors generated.
Compiler returned: 1