C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Fold expression contains 'if constexpr'

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Sun, 4 Dec 2022 18:28:50 -0500
On Sun, Dec 4, 2022 at 6:23 PM Lénárd Szolnoki via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> Hi,
>
> On 4 December 2022 22:40:25 GMT, Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> wrote:
> >I wanted to write the following function containing a fold expression:
> >
> >template<typename... Types>
> >auto Func(Types... a)
> >{
> > using std::get;
> > decltype(pointers) &p = pointers;
> >
> > (if constexpr(requires{ get<Types>(p)->Method(a...); }) return
> >get<Types>(p)->Method(a...), ...);
> >}
> >
> >but since we can't have 'if constexpr' inside a fold expression, I
> >instead had to write:
> >
> >template<typename... Types>
> >auto Func(Types... a)
> >{
> >using std::get;
> >
> >decltype(pointers) &p = pointers;
> >
> > if constexpr(requires{get< 0>(p)->Method(a...); })return get<
> >0>(p)->Method(a...);
> >else if constexpr(requires{get< 1>(p)->Method(a...); })return get<
> >1>(p)->Method(a...);
> >else if constexpr(requires{get< 2>(p)->Method(a...); })return get<
> >2>(p)->Method(a...);
> >else if constexpr(requires{get< 3>(p)->Method(a...); })return get<
> >3>(p)->Method(a...);
> >else if constexpr(requires{get< 4>(p)->Method(a...); })return get<
> >4>(p)->Method(a...);
> >else if constexpr(requires{get< 5>(p)->Method(a...); })return get<
> >5>(p)->Method(a...);
> >else if constexpr(requires{get< 6>(p)->Method(a...); })return get<
> >6>(p)->Method(a...);
> >else if constexpr(requires{get< 7>(p)->Method(a...); })return get<
> >7>(p)->Method(a...);
> >else if constexpr(requires{get< 8>(p)->Method(a...); })return get<
> >8>(p)->Method(a...);
> >else if constexpr(requires{get< 9>(p)->Method(a...); })return get<
> >9>(p)->Method(a...);
> >else if constexpr(requires{get<10>(p)->Method(a...); })return
> >get<10>(p)->Method(a...);
> >else if constexpr(requires{get<11>(p)->Method(a...); })return
> >get<11>(p)->Method(a...);
> >else if constexpr(requires{get<12>(p)->Method(a...); })return
> >get<12>(p)->Method(a...);
> >else if constexpr(requires{get<13>(p)->Method(a...); })return
> >get<13>(p)->Method(a...);
> >else if constexpr(requires{get<14>(p)->Method(a...); })return
> >get<14>(p)->Method(a...);
> >else if constexpr(requires{get<15>(p)->Method(a...); })return
> >get<15>(p)->Method(a...);
> >}
> >
> >Is there some how some way that we can allow 'if constexpr' inside a
> >fold expression? I know that we can have a fold expression containing
> >a lambda (and that the lambda can contain 'if constexpr'), but in this
> >example we need 'if constexpr' by itself.
>
> Note that apart from an if of if constexpr statement, you can't have a return statement in a fold expression either. There is absolutely no way to short-circuit a fold expression, unless it's fold over && or ||, and even then, it needs to be the built-in operator. This limits fold expressions somewhat.
>
> There were some proposals to introduce for loops over packs, I don't know the state of those. That would solve this issue quite elegantly.

The proposal is P1306: expansion statements. I don't really know what
happened to it. According to P2632, it has finished design work, but
it hasn't moved forward past EWG. It seems to be stalled out as "needs
updates". I guess the people proposing it lost interest or something.

Received on 2022-12-04 23:30:47