【KeyWord】- typename

        • Qualified and Unqualified Names
        • Dependent Names and Non-Dependent Names
        • The Problem
        • The Solution
        • typename 严禁在以下情况使用:

Qualified and Unqualified Names

#include 

int main(){
 std::cout << "Hello world!" << std::endl;   
}

the use of cout and endl began with std:: ;
A qualified name is one that specifies a scope;

Dependent Names and Non-Dependent Names

template<class T>
class MyClass {
    int i;
    vector<int> vi;
    vector<int>::iterator vitr;

    T t;
    vector vt;
    vector::iterator viter;
}

The names T,vector and vector::iterator are called “dependent names”, and the types they name are dependent types;
The names used in the first three declarations are called non-dependent names,at the types are non-dependent types;

The Problem

template<class T>
void foo() {
    T::iterator * iter; --> Declaration : you intend for a class that defined a nested type called "iterator"
    ...
};

class ContainsAType{
    class iterator { ... }  --> a type
    ...
};

foo();   --> so far so good

class ContainsAValue{
    static int iterator;    --> a value
    ...
};

foo();  --> now "T::iterator * iter" becomes a Statement that evaluates an expression

The same series of tokens can be parsed in two entirely different ways, and there’s no way to disambiguate them until instantiation.

The Solution

template<class T>
void foo(){
    typename T::iterator * iter;    --> Declaration : it states that the name "T::iterator" should be a type
    ...
}

typename states that the name that follows should be treated as a type;
Without typename , there is a C++ parsing rule that dependent names should be parsed as non-types; Thus it would be interpreted as multiplication;

typename 严禁在以下情况使用:

  1. 模板定义之外;(注意:显式模板特化(与部分特化相比,通常称为总特化)本身不是模板,因为没有缺少模板参数,因此在完全特化中,也禁止使用的;)
  2. 非限定的类型前,比如int;(限定名称 是 指定范围内的名称)
  3. 继承基类时;(因为继承的无非就是class和struct)
  4. 在构造器的初始化列表中;

你可能感兴趣的:(C/C++/C#,typename,c++)