2.1.8 Type Deduction with decltype

What was the problem

During the pre-C++11 era every variable, member, argument, etc. has to be explicitly typed. For example, if we were writing a template function operating on a range, how could we declare a variable of the type of its items?

template 
< 
  typename InputIt, 
  typename OutputIt, 
  typename Predicate, 
  typename Transform, 
> 
void transform_if 
(InputIt first, InputIt last, OutputIt out, 
 Predicate& predicate, Transform& transform) 
{ 
  for (; first != last; ++first) 
  { 
    /* some_type */ v = *first; 
    if (predicate(v)) 
    { 
      *out = transform(v); 
      ++out; 
    } 
  } 
}
How the Problem is Solved

Getting the correct type to put in place of some_type was not obvious, and required a fair share of template metaprogramming. Now, with the decltype specifier introduced in C++11, the programmer can tell the compiler to use “the type of this expression”.

template 
< 
  typename InputIt, 
  typename OutputIt, 
  typename Predicate, 
  typename Transform, 
> 
void transform_if 
(InputIt first, InputIt last, OutputIt out, 
 Predicate& predicate, Transform& transform) 
{ 
  for (; first != last; ++first) 
  { 
    decltype(*first)& v = *first; 
    if (predicate(v)) 
    { 
      *out = transform(v); 
      ++out; 
    } 
  } 
}

In the example above, decltype(*first) is the type of the result of dereferencing first.