There is one use that has not already been mentioned in C++, and that is not to refer to the own object or disambiguate a member from a received variable.
You can use this
to convert a non-dependent name into an argument dependent name inside template classes that inherit from other templates.
template <typename T>
struct base {
void f() {}
};
template <typename T>
struct derived : public base<T>
{
void test() {
//f(); // [1] error
base<T>::f(); // quite verbose if there is more than one argument, but valid
this->f(); // f is now an argument dependent symbol
}
}
Templates are compiled with a two pass mechanism. During the first pass, only non-argument dependent names are resolved and checked, while dependent names are checked only for coherence, without actually substituting the template arguments.
At that step, without actually substituting the type, the compiler has almost no information of what base<T>
could be (note that specialization of the base template can turn it into completely different types, even undefined types), so it just assumes that it is a type. At this stage the non-dependent call f
that seems just natural to the programmer is a symbol that the compiler must find as a member of derived
or in enclosing namespaces --which does not happen in the example-- and it will complain.
The solution is turning the non-dependent name f
into a dependent name. This can be done in a couple of ways, by explicitly stating the type where it is implemented (base<T>::f
--adding the base<T>
makes the symbol dependent on T
and the compiler will just assume that it will exist and postpones the actual check for the second pass, after argument substitution.
The second way, much sorter if you inherit from templates that have more than one argument, or long names, is just adding a this->
before the symbol. As the template class you are implementing does depend on an argument (it inherits from base<T>
) this->
is argument dependent, and we get the same result: this->f
is checked in the second round, after template parameter substitution.