How do you understand dependent names in C++

Dependent names are characterized by a dependency on a template argument. Trivial example:

#include <vector>

void NonDependent()
{
  //You can access the member size_type directly.
  //This is precisely specified as a vector of ints.

  typedef std::vector<int> IntVector;  
  IntVector::size_type i;

  /* ... */
}

template <class T>
void Dependent()
{

  //Now the vector depends on the type T. 
  //Need to use typename to access a dependent name.

  typedef std::vector<T> SomeVector;
  typename SomeVector::size_type i;

  /* ... */
}

int main()
{
  NonDependent();
  Dependent<int>();
  return 0;
}

EDIT: As I mentioned in the comment below, this is an example of a peculiar situation regarding the use of dependent names which appears quite frequently. Sometimes the rules governing the use of dependent names are not what one might instinctively expect.

For instance, if you have a dependent class which derives from a depenent base, but within an scope in which a name from the base class apparently doesn’t depent on the template, you might get a compiler error just like below.

#include <iostream>

template <class T>
class Dependent
{
protected:
  T data;
};

template <class T>
class OtherDependent : public Dependent<T>
{
public:
  void printT()const
  { 
    std::cout << "T: " << data << std::endl; //ERROR
  }
};

int main()
{
  OtherDependent<int> o;
  o.printT();
  return 0;
}

This error happens because the compiler will not lookup name data inside the base class template since it doesn’t dependent on T and, consequently, it is not a depedent name. The ways to fix are using this or explicitly telling the dependent base class template:

std::cout << "T: " << this->data << std::endl; //Ok now.
std::cout << "T: " << Dependent<T>::data << std::endl; //Ok now.

or placing using declaration:

template <class T>
class OtherDependent : public Dependent<T>
{
    using Dependent<T>::data; //Ok now.
    ....
};

Leave a Comment