1
#include <iostream>
#include <type_traits>
#include <math.h> 

template<typename T>
void Foo(T x)
{
    if(std::is_integral<T>::value)
    {
        rint(x);
    }
    else
    {
        std::cout<<"not integral"<<std::endl;
    }
}
int main()
{
    Foo("foo");
    return 0;
}

Does not compile because there is no suitable rint overload for const char*, but rint will never be invoked with const char* because it's not an integral type. How can I inform the compiler about this

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
oz sz
  • 13
  • 2

2 Answers2

3

One way would be to use std::enable_if as shown below:

template<typename T>
typename std::enable_if<std::is_integral<T>::value>::type Foo(T x)
{
    std::cout<<"Foo called for integral type"<<std::endl;
    rint(x);   
}
template<typename T>
typename std::enable_if<!std::is_integral<T>::value>::type Foo(T x)
{
    std::cout<<"non-integral type"<<std::endl;
       
}
int main()
{
    Foo(5);// calls Foo integral type
    Foo('c'); //calls Foo for integral type
    Foo("c"); //call Foo for non-integral type
    return 0;
}
Jason
  • 36,170
  • 5
  • 26
  • 60
2

In c++17 you could use if constexpr instead of if and it would work.

In c++14 you could specialize a struct to do what you want

template<class T, bool IsIntegral = std::is_integral<T>::value>
struct do_action
{
    void operator()(T val) { rint(val); }
};

template<class T>
struct do_action<T, false>
{
    void operator()(T val) { std::cout << "Not integral\n"; }
};

template<class T>
void Foo(T x)
{
    do_action<T>()(x);
}
Mestkon
  • 3,532
  • 7
  • 18