https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89417
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Federico Kircheis from comment #6) > For what is worth, I imagined the implementation for parameters of different > type and more or less than two to be similar to > > ---- > template <class...Args> > auto sorted_indexes(Args&... args) { > const void* addresses[] = {&args...}; > std::array<int,std::size(addresses)> indexes{}; > std::iota(std::begin(indexes), std::end(indexes), 0); > std::sort(std::begin(indexes), std::end(indexes), [&](int i1, int i2){ > return std::less<void>()(addresses[i1], addresses[i2]); > }); > return indexes; > } > > > template <class...Args> > auto create_lock(Args&... args){ > auto indexes = sorted_indexes(args...); > return std::scoped_lock(args[indexes]...); // ??? > } > ---- > > But it's probably a dead end, as args is not an array and I see no way to > use the computed index. args is not an array and indexes is not a pack. You could make sorted_indexes a constexpr function that returns a std::index_sequence holding the sorted indices, then: template<class T, size_t... I> auto create_lock_impl(std::index_sequence<I...>, T arg_tuple, ) { return std::scoped_lock(std::get<I>(args)...); } template<class... Args> auto create_lock(Args&... args) { return create_lock_impl(sorted_indexes(args...), std::tie(args...)); } But I am still unconvinced it's worth changing anything here.