4

Consider function template<typename T> void Fun(T t);. How can I have different implementations of it for integral and floating types respectively?

I guess building blocks are std::enable_if, std::is_integral, std::is_floating_point. But I cannot put them together in an elegant way :-( .

P.S. I got C++11 available.

David G
  • 94,763
  • 41
  • 167
  • 253
updogliu
  • 6,066
  • 7
  • 37
  • 50
  • Instead of `enable_if`/SFINAE, you can also use [tag dispatch](http://stackoverflow.com/q/6917079/420683). Tag dispatch is often simpler and more straight-forward, but can require slightly more code. – dyp Feb 23 '14 at 20:19

1 Answers1

8

See the example code for std::enable_if on cppreference.com.

EDIT:

Adapted the code from the link above as follows:

#include <type_traits>
#include <iostream>


template<class T>
typename std::enable_if<std::is_integral<T>::value>::type foo(T t) 
{
    std::cout << "is integral" << std::endl;
}

template<class T>
typename std::enable_if<std::is_floating_point<T>::value>::type foo(T t) 
{
    std::cout << "is real" << std::endl;
}

int main()
{
    foo(1); 
    foo(1.0);
}

The definition of enable_if is template< bool B, class T = void > struct enable_if;. This gives the following options for return value type:

template<class T>
typename std::enable_if<std::is_integral<T>::value>::type foo(T t) // void return type

template<class T>
typename std::enable_if<std::is_integral<T>::value, T>::type foo(T t) // return type from template parameter

template<class T>
typename std::enable_if<std::is_integral<T>::value, size_t>::type foo(T t) // fixed return type
TAS
  • 2,039
  • 12
  • 17
  • I asked this question after came back from there. Just edited my question. My function have fix return type. So the tricks at cppreference.com do not apply. – updogliu Feb 23 '14 at 19:47
  • @updogliu `enable_if` actually has two template parameters, the second one is defaulted to `void`. When the condition (the first template parameter) is `true`, `std::enable_if<..>::type` yields the *second* template parameter (here: `void`). If that's still a problem, you can use `enable_if` on a defaulted additional template parameter of `foo`, e.g. `template::type> void foo(T);` – dyp Feb 23 '14 at 20:16
  • 2
    In C++14 the return type can be slightly simplified to `std::enable_if_t::value>` (i.e. no preceding `typename` and no `::type` at the end - for the cost of adding a strategic "_t"). – Howard Hinnant Feb 23 '14 at 20:37