https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448
Bug ID: 103448 Summary: unexpected tuple collapse Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: janezz55 at gmail dot com Target Milestone: --- Here you have a fully working program, that instead of creating a std::tuple<std::tuple<int&, int&>> creates a std::tuple<int&, int&> something collapses the tuple of tuples into a single tuple. The workaround is to replace the std::tuple() constructor call with a std::make_tuple() call. https://wandbox.org/permlink/Q5P8iaUjThDKxJL9 #include <iostream> #include <tuple> #include <string_view> template <typename T> constexpr auto type_name() { std::string_view name, prefix, suffix; #ifdef __clang__ name = __PRETTY_FUNCTION__; prefix = "auto type_name() [T = "; suffix = "]"; #elif defined(__GNUC__) name = __PRETTY_FUNCTION__; prefix = "constexpr auto type_name() [with T = "; suffix = "]"; #elif defined(_MSC_VER) name = __FUNCSIG__; prefix = "auto __cdecl type_name<"; suffix = ">(void)"; #endif name.remove_prefix(prefix.size()); name.remove_suffix(suffix.size()); return name; } template <std::size_t N> constexpr auto split(auto&& t) noexcept requires(bool(N)) { constexpr auto n(std::tuple_size_v<std::remove_cvref_t<decltype(t)>>); static_assert(n && !(n % N)); return [&]<auto ...I>(std::index_sequence<I...>) noexcept { return std::tuple( [&]<auto ...J>(std::index_sequence<J...>) noexcept { constexpr auto K(N * I); return std::forward_as_tuple(std::get<K + J>(t)...); }(std::make_index_sequence<N + I - I>())... ); }(std::make_index_sequence<n / N>()); } int main() { auto t(split<2>(std::tuple(1, 2))); std::cout << type_name<decltype(t)>() << std::endl; return 0; }