Home > Net >  Simultaneously existing a template function with std::enable_if and an ordinary template function
Simultaneously existing a template function with std::enable_if and an ordinary template function

Time:11-17

I have a simple function:

template<class T>
typename std::enable_if_t<std::is_arithmetic_v<T>>
foo(T val) { }

I would like also to have another function with the same name:

template<class T>
void foo(T value) { }

I want to call the first function with arithmetic types and the second function for all other types. An idea I have is to change the second function into this:

template<class T>
typename std::enable_if_t<!std::is_arithmetic_v<T>>
foo(T val) { }

but is there a better way to achieve that?

CodePudding user response:

A better and more intuitive way is to use C 20 concepts.

#include <concepts>

template<class T>
  requires std::is_arithmetic_v<T>
void foo(T value) { }

template<class T>
void foo(T value) { }

When you call foo(0), since the constraint of the first overload is satisfied, it will take precedence over the second unconstrainted overload.

When you call foo("hello"), since the constraint of the first overload is not satisfied, the compiler will select the second overload.

CodePudding user response:

Use if constexpr:

template<class T>
void foo(T value)
{
  if constexpr (std::is_arithmetic_v<T>) {
    // ... one implementation
  } else {
    // ... another implementation
  }
}

CodePudding user response:

You can do it by leverage overload resolution:

template<class T>
typename std::enable_if_t<std::is_arithmetic_v<T>>
foo(T val, int)
{
    std::cout << "arithmetic: " << (val   val) << '\n';
}

template<typename T>
void foo(const T& val, long)
{
    std::cout << "Def: " << val << '\n';
}

template<typename T>
void foo(T&& x)
{
    foo(std::forward<T>(x), 0);
}

https://godbolt.org/z/sM1KbT8vE

now int overload is preferred, but if it fails because of SFINAE it jumps to long overload.

In simple case I prefer !std::eneble_if_t approach, but if you have more special cases overload resolution is more handy.

  • Related