C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Make std::make_from_tuple SFINAE friendly

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Sun, 31 Mar 2024 19:01:44 +0000
On Fri, 29 Mar 2024 at 15:29, Yrong via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Hello,
>
> I was wondering if I can submit this improvement as a short proposal paper
> .
>
> *Discussion:*
>
> LWG3528 constraint *`*constexpr T *make-from-tuple-impl*(Tuple&& t,
> index_sequence<I...>)*` with `*requires is_constructible_v<T,
> decltype(get<I>(declval<Tuple>()))...>`.
> When someone write SFINAE code like below to check whether T can make from
> tuple, they may meet hard errors like "*no matching function for call to
> 'make-from-tuple-impl'...*".
>
> ```
> template <class T, class Tuple, class = void>
> inline constexpr bool has_make_from_tuple = false;
>
> template <class T, class Tuple>
> inline constexpr bool
> has_make_from_tuple<T, Tuple, std::void_t<decltype(std::make_from_tuple<T>(std::declval<Tuple>()))>>
> = true;
>
> struct A { int a; };
>
> static_assert(!has_make_from_tuple<int*, std::tuple<A*>>);
> ```
>
>
> *Proposed resolution:*
>
> This wording is relative to N4971 <https://wg21.link/N4971>.
>
> 1.
>
> Edit 22.4.6 [tuple.apply] <https://wg21.link/tuple.apply> as indicated:
>
> template<class T, *tuple-like*
> <https://eel.is/c++draft/tuple.like#concept:tuple-like> Tuple> constexpr
> T make_from_tuple(Tuple&& t); *-3- Let I be the pack 0, 1, ...,
> (tuple_size_v<remove_reference_t<Tuple>> - 1).*-4- Constraints:
> is_constructible_v<T, decltype(get<I>(declval<Tuple>()))...> is true.
> -5- *Mandates*: If tuple_size_v<remove_reference_t<Tuple>> is 1, then
> reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>())
> )> is false. <https://eel.is/c++draft/tuple.apply#3.sentence-1>
>
> -6- *Effects*: Given the exposition-only function template:
> namespace std { template<class T, *tuple-like*
> <https://eel.is/c++draft/tuple.like#concept:tuple-like> Tuple, size_t... I
> > requires is_constructible_v<T, decltype(get<I>(declval<Tuple>()))...>
> constexpr T *make-from-tuple-impl*(Tuple&& t, index_sequence<I...>) { // *exposition
> only* return T(get<I>(std::forward<Tuple>(t))...); } }
> Equivalent to:return *make-from-tuple-impl*<T>( std::forward<Tuple>(t),
> make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});
>
> [*Note 1*:
> The type of T must be supplied as an explicit template parameter, as it
> cannot be deduced from the argument list.
> <https://eel.is/c++draft/tuple#apply-4.sentence-2>
> — *end note*]
>
>
If the effects are "Equivalent to" calling a constrained function, don't
the constraints apply to std::make_from_tuple already?

Received on 2024-03-31 19:03:04