Date: Wed, 16 Nov 2022 15:02:26 +0000
On Wed, 16 Nov 2022 at 14:44, Jason McKesson via Std-Discussion <
std-discussion_at_[hidden]> wrote:
> On Wed, Nov 16, 2022 at 5:00 AM Zamfir Yonchev via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> >
> > Hi,
> >
> > I was wondering why the language doesn't support short-circuiting on
> logical operations in constexpr context.
>
> It does. The rules of short-circuit evaluation don't change because
> something is in a constant expression. Your problem is not a lack of
> short-circuit evaluation; your problem is that short-circuit
> evaluation doesn't mean what you think it does.
>
> `std::invoke_result_t<F, T>` is ill-formed if `F` is not invokable.
> That is not a matter of expression evaluation; that's a matter of
> template instantiation. It's not the result of the evaluation that is
> ill-formed; it's the *existence* of the expression itself. The literal
> text of the source code makes no sense, as far as the language is
> concerned. It is no different than if you wrote `a + - + - + c`.
>
> The compiler doesn't get to the point where it would even consider
> evaluating the expression because the code doesn't make sense.
>
> `if constexpr` has explicit rules allowing it to discard statements
> depending on the result of the constant expression. But that is a
> special grammatical construct explicitly designed with this
> functionality in mind.
>
> So the reason why what you wrote doesn't work is because there is no
> special expression-level construct that was added to the language to
> allow discarding of subexpressions in the same way that `if constexpr`
> can discard statements.
>
Ahem. Actually, we do have such a construct in the evaluation of
constraints. You can make use of that mode by wrapping your test in
`requires requires`:
constexpr bool test = requires { requires std::is_invocable_v<F, T> &&
std::is_same_v<std::invoke_result_t<F, T>, int>; };
Demo: https://godbolt.org/z/7q5dvKnsn
https://eel.is/c++draft/expr.prim.req.general#5.sentence-3
std-discussion_at_[hidden]> wrote:
> On Wed, Nov 16, 2022 at 5:00 AM Zamfir Yonchev via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> >
> > Hi,
> >
> > I was wondering why the language doesn't support short-circuiting on
> logical operations in constexpr context.
>
> It does. The rules of short-circuit evaluation don't change because
> something is in a constant expression. Your problem is not a lack of
> short-circuit evaluation; your problem is that short-circuit
> evaluation doesn't mean what you think it does.
>
> `std::invoke_result_t<F, T>` is ill-formed if `F` is not invokable.
> That is not a matter of expression evaluation; that's a matter of
> template instantiation. It's not the result of the evaluation that is
> ill-formed; it's the *existence* of the expression itself. The literal
> text of the source code makes no sense, as far as the language is
> concerned. It is no different than if you wrote `a + - + - + c`.
>
> The compiler doesn't get to the point where it would even consider
> evaluating the expression because the code doesn't make sense.
>
> `if constexpr` has explicit rules allowing it to discard statements
> depending on the result of the constant expression. But that is a
> special grammatical construct explicitly designed with this
> functionality in mind.
>
> So the reason why what you wrote doesn't work is because there is no
> special expression-level construct that was added to the language to
> allow discarding of subexpressions in the same way that `if constexpr`
> can discard statements.
>
Ahem. Actually, we do have such a construct in the evaluation of
constraints. You can make use of that mode by wrapping your test in
`requires requires`:
constexpr bool test = requires { requires std::is_invocable_v<F, T> &&
std::is_same_v<std::invoke_result_t<F, T>, int>; };
Demo: https://godbolt.org/z/7q5dvKnsn
https://eel.is/c++draft/expr.prim.req.general#5.sentence-3
Received on 2022-11-16 15:02:40