Search code examples
c++templatesstltype-traits

C++ STL type_traits question


I was watching the latest C9 lecture and noticed something interesting..

In his introduction to type_traits, Stephan uses the following (as he says, contrived) example:

template <typename T> void foo(T t, true_type)
{
    std::cout << t << " is integral";
}
template <typename T> void foo(T t, false_type)
{
    std::cout << t << " is not integral";
}

template <typename T> void bar(T t) { foo(t, typename is_integral<T>::type()); }

This seems to be far more complicated than:

template <typename T> void foo(T t)
{
    if(std::is_integral<T>::value)
        std::cout << "integral";
    else
        std::cout << "not integral";
}

Is there something wrong with the latter way of doing it? Is his way better? Why?

Thanks.


Solution

  • The example below should illustrate the difference. Let's add struct X:

    struct X
    {
      X(int)
      {
      }
    };
    

    and modify one foo as below:

    template <typename T> void foo(T t, true_type)
    {
        std::cout << t << " is integral";
        X x(t);
    }
    template <typename T> void foo(T t, false_type)
    {
        std::cout << t << " is not integral";
    }
    

    Then:

    template <typename T> void bar(T t)
    {
        foo(t, typename is_integral<T>::type());
    }
    

    Will still compile for all T types (including integer types; it may cause warning but will compile).

    The other equivalent code:

    template <typename T> void foo(T t)
    {
        if(std::is_integral<T>::value)
        {
            std::cout << "integral";
            X x(t);
        }
        else
            std::cout << "not integral";
    }
    

    will often fail to compile as you will not be able to instantiate X for types other then integral and eventually floating point and user defined classes which have operator int() (operator short() or operator long() will not do).