Home > Enterprise >  Why is there no (implicit) conversion from std::tuple<Ts...>& to std::tuple<Ts&...>?
Why is there no (implicit) conversion from std::tuple<Ts...>& to std::tuple<Ts&...>?

Time:02-25

  1. As the title states, is there a specific reason why there is no (implicit) conversion from std::tuple<Ts...>& to std::tuple<Ts&...>? In contrast, the tuple implementation of EASTL provides this conversion.
#include <EASTL/tuple.h>

#include <tuple>

#include <type_traits>

int main()
{
  using TupleRef = std::tuple<int, float>&;
  using RefTuple = std::tuple<int&, float&>;

  using EATupleRef = eastl::tuple<int, float>&;
  using EARefTuple = eastl::tuple<int&, float&>;

  // static_assert(std::is_convertible_v<TupleRef, RefTuple>); // fails to compile
  static_assert(std::is_convertible_v<EATupleRef, EARefTuple>);

  return 0;
}
  1. What do I have to change/add, if I reimplemented the STL tuple implementation?

Here is a link to godbolt show-casing the problem: https://godbolt.org/z/zqfrETKEz

PS: I used the c 17 flag in godbolt since EASTL does not compile with the c 20 flag, but I am also interested in a c 20 solution.

CodePudding user response:

There will be in , as a result of the zip paper (P2321).


Generally speaking, it is typical for overload sets to have one overload taking T const& and another overload taking T&&, it's not often that T& is needed as a distinct 3rd option (and T const&& even less so). This is one of those cases that originally had just the two, but then really does need at least the 3rd.

I'm not sure if you had a particular motivation for needing tuple<int>& to be convertible to tuple<int&>, but zip needs that to work, which is why it changed.

  • Related