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;
}
}
}
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.