dimanche 6 janvier 2019

if constexpr vs sfinae

With the introduction of if constexpr in c++17, some problems which were solved by using compile-time SFINAE in c++14/c++11 can now be solved using if constexpr, with an easier syntax.

Consider, e.g., the following basic example of a compile-time recursion to produce a subroutine which prints a variable number of arguments.

#include <iostream>
#include <type_traits>

template <typename T>
void print_sfinae(T&& x)
{
  std::cout << x << std::endl;
}

template <typename T0, typename... T>
std::enable_if_t<(sizeof...(T) > 0)> print_sfinae(T0&& x, T&&... rest)
{
  std::cout << x << std::endl;
  print_sfinae(std::forward<T>(rest)...);
}

template <typename T0, typename... T>
void print_ifconstexpr(T0&&x, T&&... rest)
{
  if constexpr (sizeof...(T) > 0)
         {
            std::cout << x << std::endl;
            print_ifconstexpr(std::forward<T>(rest)...);
         }
  else
      std::cout << x << std::endl;
}

int main()
{
  print_sfinae(5, 2.2, "hello");
  print_ifconstexpr(5, 2.2, "hello");

  return 0;
}

The routine print_sfinae uses sfinae techniques from c++11, whereas print_ifconstexpr does the same job by using if constexpr.

Can one assume that the compiler, on evaluating the if constexpr completely discards the non-verified condition and generate code only for the branch which satisfy the if constexpr condition? Does the standard specifies such a behavior for the compiler?

More generally, in terms of efficiency and generated code, are solutions based on if constexpr identical to the equivalent solutions based on pre-c++17 sfinae?

Aucun commentaire:

Enregistrer un commentaire