C++ Logo

std-discussion

Advanced search

short-circuiting logical operations on constexpr predicates

From: Zamfir Yonchev <zamfir.yonchev_at_[hidden]>
Date: Wed, 16 Nov 2022 11:59:53 +0200
Hi,

I was wondering why the language doesn't support short-circuiting on
logical operations in constexpr context.
It would be very useful to avoid evaluating certain compile-time
expressions if they are not needed for the result of the logic expression,
especially if they are ill-formed.

Consider the following code snippet:
```
#include <type_traits>
template<typename F, typename T>
void foo(F f, T t)
{
  constexpr bool test = std::is_invocable_v<F, T> &&
std::is_same_v<std::invoke_result_t<F, T>, int>;
  if constexpr ( test ) { /*do something*/ }
  else { /*do something else*/ }
}

void test()
{
  foo([](){}, 42); //error: no type named 'type' in 'struct
std::invoke_result<main()::<lambda()>, int>'
}
```

I know that for this particular case we have `is_invocable_r` but the code
is just for illustrative purposes. I'm talking in general.

The way we have to do it currently is like this (if we ignore
is_invocable_r) :
```
template<typename F, typename T>
void foo(F f, T t)
{
  if constexpr ( std::is_invocable_v<F, T> )
  {
    constexpr bool test = std::is_same_v<std::invoke_result_t<F, T>, int>;

    if constexpr ( test ) { /*do something*/ }
    else { /*do something else*/ }
  }
  else { /*do something else*/ } //not DRY
}
```
The main problem is we have to repeat the else statement. And if we have
several such checks the amount of if-else branches grows exponentially.

I don't have much experience with concepts and I'm not sure if they can
help in this situation. But even if they can, we'll still have to write
ad-hoc concepts for each place where we need this kind of short-circuiting.

I know the short answer to my question is "because it doesn't" but is there
a reason they decided to go with the full evaluation rather than the
short-circuiting evaluation?
Runtime evaluation of logical expressions still uses short-circuiting and
many programmers use it to their advantage by writing unsafe operations
that are guarded by safety checks in one expression.

Thanks,
Zamfir Yonchev

Received on 2022-11-16 10:00:06