tags:

views:

64

answers:

3

This is the statement from ISO C++ Standard 14.6/8:

When looking for the declaration of a name used in a template definition, the usual lookup rules are used for nondependent names. The lookup of names dependent on the template parameters is postponed until the actual template argument is known (14.6.2).

Example:

  #include <iostream>
  using namespace std;
  template<class T> class Set {
            T* p;
            int cnt;
  public:
            Set();
            Set<T>(const Set<T>&);
            void printall()
            {
                        for (int i = 0; i<cnt; i++)
                                   cout << p[i] << ’\n’;
            }
            // ...
  };

in the example, i is the local variable i declared in printall, cnt is the member cnt declared in Set,and cout is the standard output stream declared in iostream. However, not every declaration can be found this way; the resolution of some names must be postponed until the actual template-arguments are known. For example, even though the name operator<< is known within the definition of printall() and a declaration of it can be found in , the actual declaration of operator<< needed to print p[i] cannot be known until it is known what type T is (14.6.2).

Iam unable to understand this point...and the example too?

can any one tell an other example for this statement...please

+1  A: 
T* p;
...
for (int i = 0; i<cnt; i++)
    cout << p[i] << ’\n’;

basically, you do not know if cout << p[i] << ’\n’; is valid expression (for example) until you know the type T

aaa
+3  A: 

Looking only at the template, can you tell me what the type of p[i] is? No. The type of p[i] in Set<int> will be int ; the type of p[i] in Set<std::string> will be std::string. Hence, the lookup of operator<< has to be delayed until the template is instantiated and the type of p[i] is known.

You'd have a similar issue in (assume this is another member of Set<T>)

// In Set<T>
void reverse()
{
  for (int i = 0; i <= cnt-i; ++i)
  {
    using std::swap;
    swap(p[i], p[cnt-i]);
  }
}

The lookup of swap will also need the type of p[i], even though there's a using declaration directly in front.

MSalters
+1  A: 

Templates have concept of dependent name and non-dependent name. Dependent names, simply speaking are those that somehow depend on the template parameter. In your code 'T *p', makes 'p' a dependent name as it depends on the template parameter T

Now cout << p[i] requires an overload of operator << like so

ostream& operator << (ostream &os, T const &t);

or an overload of operator << to which 'T' can be converted.

But is such an overload available? How does the compiler know this until 'T' is known?

This is exactly what the above quote from the Standard talks about.

Names such as 'i' etc are non-dependent as they do not depend on the template parameter in any way. Hence lookup of such non-dependent names can be resolved immediately even though 'T' is not known

Chubsdad