C ++ STL type_traits question

I watched the last lecture of C9 and noticed something interesting.

In his introduction to type_traits, Stefan uses the following (as he says, far-fetched) 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";
}

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

code>

This looks a lot more complicated than:

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

Is there something wrong with the last way to do this? Is his way better? Why?

Thank.

+3
source share
4 answers

The example below should illustrate the difference. Let structure X be added:

struct X
{
  X(int)
  {
  }
};

and change 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 compile for all types of T (including integer types, this may cause a warning, but will compile).

Another 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";
}

, X , , , , int() ( short() long() ).

+9

"" - .

, , .

+14

, , . , . if/switch - . ; .

, - (, , ), . ( - ?), , , , .

+1

Using the first approach, you can implement static-dispatch without using if/elseor switch.

template <typename T> 
void Dispatch(T t)
{
    //Call foo(T, true_type) or foo(T, false_type)
    //depending upon the *type* of second parameter.
    foo(t, typename is_integral<T>::type());
}

Using the second approach, you must implement this with a block if/elseor switch,

template <typename T> 
void Dispatch(T t)
{
    //Call foo(T, true_type) or foo(T, false_type)
    //depending upon the *value* of value.
    if(std::is_integral<T>::value)
        foo(t, true_type());
    else
        foo(t, false_type());
}

But if you want to implement your Dispatch()function without using if/else, and at the same time you want to use std::is_integral<T>::value, then you need to re-write your function foo(), for example,

template <bool b> 
void foo(T t)
{
    std::cout << t << " is integral";
}

template <> 
void foo<false>(T t)
{
    std::cout << t << " is not integral";
}

And your function Dispatch()will look like

 template <typename T> 
 void Dispatch(T t)
 {
     //using std::is_integral<T>::value!
     const bool selector = (bool) std::is_integral<T>::value;
     foo<selector>(t);
 }
0
source

Source: https://habr.com/ru/post/1782736/


All Articles