模板:名称解析 - >任何人都可以为此声明告诉另一个示例...请

时间:2010-09-20 06:51:09

标签: c++ templates

这是ISO C ++标准14.6 / 8的声明:

  

在查找模板定义中使用的名称声明时,通常的查找规则用于非依赖名称。依赖于模板参数的名称查找被推迟,直到知道实际模板参数(14.6.2)。

示例:

  #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’;
            }
            // ...
  };

在示例中,i是我在printall中声明的局部变量,cnt是在Set中声明的成员cnt,cout是在iostream中声明的标准输出流。但是,不是每一个声明都可以这样找到;必须推迟一些名称的解析,直到知道实际的模板参数。例如,即使名称运算符&lt;&lt;在printall()的定义中已知,并且可以在运算符的实际声明中找到它的声明&lt;&lt;需要打印p [i]直到知道T是什么类型才能知道(14.6.2)。

我无法理解这一点......以及这个例子呢?

任何人都可以告诉另一个这样的例子......请

3 个答案:

答案 0 :(得分:2)

只看模板,你能告诉我p[i]的类型是什么吗?不会。p[i]中的Set<int>类型为int; p[i]Set<std::string>的类型将为std::string。因此,operator<<的查找必须延迟,直到模板被实例化并且p[i]的类型已知。

你有一个类似的问题(假设这是Set<T>的另一个成员)

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

交换的查找也需要p[i]的类型,即使前面有一个使用声明。

答案 1 :(得分:0)

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

基本上,在知道类型cout << p[i] << ’\n’;

之前,您不知道T是否为有效表达式(例如)

答案 2 :(得分:0)

模板具有dependent namenon-dependent name的概念。简而言之,从属名称是以某种方式依赖于模板参数的名称。在代码'T * p'中,使'p'成为依赖名称,因为它取决于模板参数T

现在cout << p[i]需要重载operator <<,如此

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

operator <<的重载,可以转换'T'。

但这样的过载是否可用?在“T”已知之前,编译器如何知道这一点?

这正是标准上述引用的内容。

诸如'i'等名称是非依赖的,因为它们不以任何方式依赖于模板参数。因此,即使'T'未知

,也可以立即解析这些非依赖名称的查找