C++ Logo


Advanced search

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

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Mon, 12 Dec 2022 13:08:01 -0500
On Sun, Dec 4, 2022 at 5:40 PM Frederick Virchanza Gotham via Std-Proposals
<std-proposals_at_[hidden]> wrote:

> I wanted to write the following function containing a fold expression:
> [...]
> but since we can't have 'if constexpr' inside a fold expression [...]
> 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.

Interesting use-case, but the example program suffers from unnecessary
complexity, which I think sidetracked several responders.
Here's a worked example of what I believe you're trying to do: first in a
non-variadic form `f` with just two arguments, and then in a variadic form
`g` with an arbitrary number of arguments. (The link includes many test

template<class T, class U>
auto f(T t, U u) {
    if constexpr (requires { t*2; }) return t*2;
    else if constexpr (requires { u*2; }) return u*2;

template<class... Ts>
auto g(Ts... ts) {
    return *???*;

As you said: We want `g` to just "fold over `if constexpr else`," but there
doesn't seem to be an *easy* way to do that in C++23.

This is related to the proposals for folding over ?: (P1012 "Ternary Right
Fold Expression", Frank Zingsheim, Nov 2020)
  (* Frank has an unpublished P1012R2 at
https://github.com/zingsheim/ProposalTernaryFold/ ; I don't know why it was
never published in a mailing.)
and if-constexpr-ifying the condition of ?: (I thought there was a formal
proposal here, but maybe I'm wrong)
https://lists.isocpp.org/std-proposals/2021/10/3238.php (Hui Xie, Oct 2021)
https://lists.isocpp.org/std-proposals/2021/10/3241.php (Mohit Saini points
out that a macro can solve Hui's issue, but not Frederick's original)

If we had *both* of those features, then I think you could implement `g` as

template<class... Ts>
auto g(Ts... ts) {
    return (requires { ts*2; } constexpr ? ts*2 : ... : void());

I don't *like* this proposed syntax at all; but I agree that the status quo
is terrible, unless I'm missing something.

Here's a StackOverflow thread on the same topic.

I'll bring this up on the Slack, <https://cppalliance.org/slack/> too, in
case anyone has any good ideas there.


Received on 2022-12-12 18:08:15