0

I am trying to understand the utility of if constexpr and want to know if there is any utility in using it in this way.

template<bool B>
int fun()
{
    if constexpr (B)
        return 1;
    return 0;
}

Is this function changed at all by using if constexpr instead of a regular if? I assume the performance would be the same. My understanding of templates is that the outcome of the if statement is already known at compile time so there is no difference.

max66
  • 65,235
  • 10
  • 71
  • 111
jmcd
  • 15
  • 5
  • 6
    The utility of if constexpr lies in the fact that the statements in the branch that is not taken are *not instantiated*, so one could use if constexpr where a regular if would yield a type error. – n. m. could be an AI Jan 02 '23 at 21:28
  • 1
    From experience I noticed that `if constexpr` is only really useful with proper `else` or another `else if constexpr`. Otherwise the fallback instruction is always instantiated which is normally not wanted. – prapin Jan 02 '23 at 21:58

1 Answers1

5

Utility of constexpr?

A trivial example... if you write the following function

template <typename T>
auto foo (T const & val)
{
   if ( true == std::is_same_v<T, std::string>> )
      return val.size()
   else
      return val;
}

and call it with an integer

foo(42);

you get a compilation error, because the instruction

val.size();

has to be instantiated also when val is an int but, unfortunately, int isn't a class with a size() method

But if you add constexpr after the if

// VVVVVVVVV
if constexpr ( true == std::is_same_v<T, std::string>> )
   return val.size()

now the return val.size(); instruction is instantiated only when T is std::string, so you can call foo() also with arguments without a size() method.

---- EDIT ----

As @prapin observed in a comment (thanks!), if constexpr can be necessary for an auto function.

I propose another trivial (and silly) example

Without if constexpr, the following bar() function

template <typename T>
auto bar (T const &)
{
   if ( true == std::is_same_v<T, std::string>> )
      return 42;
   else
      return 42L;
}

doesn't compile, because the first return return a int value, the second return a long; so, given that without if constexpr the compiler must instantiate both return's, so the compiler can't conciliate the returns types and can't determine the return type of the function.

With if constexpr,

   if constexpr ( true == std::is_same_v<T, std::string>> )
      return 42;
   else
      return 42L;

the compiler instantiate the first return or the second one; never both. So the compiler ever determine the type returned from the function (int when called with a std::string, long otherwise).

max66
  • 65,235
  • 10
  • 71
  • 111
  • 2
    Also, as your example in fact suggests with the `auto` return type, with `if constexp` each branch is allowed to return a *different* type, which is not possible with a normal `if`. – prapin Jan 02 '23 at 21:55
  • @prapin - Good point. Simple to explain and useful. Added in my answer. Thanks! – max66 Jan 02 '23 at 22:14