What's the constexpr-if equivalent to `condition ? x : y`? As far as I know we only have `[&] { if constexpr (condition) return x; else return y; }()`. I hate it.

#cpp #cplusplus #WG21

@mkretz I might have a knot in my head, but couldn't you just do a simple constexpr operator? overload?
@funkylab Oh if I could overload `operator?:` I'd be dancing for joy. No I still have to get that paper through WG21/EWG.
But it wouldn't help. An operator can not return a different type depending on its function arguments. (unless you make the condition a `std::cw<condition>`/true_type/false_type ... interesting ... another pattern to add to my "make ?: overloadable" paper?)
@mkretz I thought the conditional operator was the singular exception to that rule; `auto val = condition ? 12 : std::string{"oats"};`
the type of `val` very much depends on the value of `condition`. Indeed, a bit annoying you can't overload that now that this type system exception exists.
@funkylab No, the type of `val` is the common type of the two expressions following the `?`. That's why `std::common_type<T, U>` is defined in terms of `?:`.
@mkretz uff yes; and I feel like I've stumbled across this very same thing before

@mkretz
Correct.

AFAIK, nobody ever proposed an equivalent.

What would your envisioned semantic look like?

* no search for a 'common type'?
* one of the two 'sub-expressions' is 'discarded', like in https://eel.is/c++draft/stmt.if#2 ?

[stmt.if]

@DanielaKEngert The semantics would be as-if it's the lambda expression I used. So yes, no common type and one sub-expression is discarded. I need the latter for `has_subscript_operator ? x[0] : x`: This does not compile because if `has_subscript_operator == false` the `x[0]` expression is ill-formed.
@mkretz
So, a simple named function would do in this case because it would depend only on the type of 'x'?
@DanielaKEngert You're thinking of `select<condition>(x[0], x)`? That would not work because `x[0]` can be ill-formed.

@mkretz
No, similar to a templated function like this

template <typename T>
auto first_in(const T &x) {
if constexpr (some_cond_based_on_T)
return x[0];
else
return x;
}

@DanielaKEngert In the case that triggered my post, yes I could work around it via such a function. But the condition is actually a trait of the class where it is used to initialize a data member. If there's a mismatch with the type then I want it to be ill-formed. This is pedantic, since the trait of the class basically is derived from that type again. But you know ... refactorings in the future ... who knows.
I have many of such lambdas. It's just annoying.

@mkretz
Propose "do expressions" 🤭

Oh wait, Barry already did that AFAIK. They are an important building block for 'pattern matching' as proposed. Otherwise it would become as annoying as in your use-case.

@DanielaKEngert @mkretz do expressions as proposed don't help me in many situations because they destroy temporaries eagerly and not deferred until the end of the full expression.

@foonathan @mkretz

Oh shoot. 💩

OTOH, this would open another venue for Nico to give highly oninionated talks 😂

@mkretz If you want to propose `? constexpr` I'd be happy to co-author but I don't think the chances are good.
@foonathan You're right that it requires different syntax. It's basically introducing another operator. I'd hate that too. Something with more appeal to me:
_M_data(if constexpr(_S_is_scalar) x[0] else x)
edit: And yes, I realize it's just another spelling for an operator.
@foonathan @mkretz
It would effectively become a new kind of operator with all the wording connected to such an endeavour.