Why does std :: get not have a single signature that accepts a forwarding link

Why std::get

to std::tuple

have so many overloads ( http://en.cppreference.com/w/cpp/utility/tuple/get )? One of them matches any possible combination of const

&

and &&

? With every combination, ref ref opponents for the return value are the same. Why not just have one overload that takes a tuple type by forwarding a reference and then just forwards the return value based on the input signature? Something like that

template <int Index, typename TupleType>
decltype(auto) get(TupleType&& tup);

      

Things like this will make it easy for people to understand what the function does get

and avoid bugs like Issue 2485 ( https://wg21.cmeerw.net/lwg/issue2485 )

+3


source to share


2 answers


std::get

existed before decltype(auto)

. It was easy.

Ok, why not change it?

The body is std::get

not specified by the standard and should not be the same as different compilers have different layouts and implementations of tuples.



decltype(auto)

does not tell the reader of the standard, user, or compiler developer what the return type is. He simply says that he is taken out of the body. What standard is not specified.

So in standard form it would be useless unless they describe what value was returned separately, which will end up like an overload.

+4


source


The parameter std::get

cannot be inferred because it std::get

is defined for different types. (Example tuple

, pair

, array

, variant

).

For this reason, more than anyone else, std::get

it cannot infer its parameter type. By changing it to output at this point, it would break real code, such as types inferred from a tuple. For example, a proposed signature change will yield a signature, e.g .: template <class TupleLike, class = enable_if_t<IsStdTuple<TupleLike>::value>>> decltype(auto) get(TupleLike&&);



This signature does not allow implicit conversions to the tuple type in the interface, as the old signatures did. As mentioned, this breaks down types that are inferred from std::tuple

or types for which the conversion operator is std::tuple

.

LibC ++ implements conversion constructors tuple

, pair

and array

using one common TupleLike

overload. As a maintainer, I am familiar with these implementation issues and if I could implement an appropriate std::get

one as you suggest I would already be.

+2


source







All Articles