Michal
Michal

Reputation: 679

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

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?

Upvotes: 0

Views: 129

Answers (3)

j6t
j6t

Reputation: 13617

Use if constexpr:

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

Upvotes: 2

Marek R
Marek R

Reputation: 38181

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.

Upvotes: 1

康桓瑋
康桓瑋

Reputation: 43096

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.

Upvotes: 2

Related Questions