模板中的依赖类型使用 --- typename

        依赖类型,顾名思义就是依赖于模板参数的类型,在使用这种类型时,必须使用 typename,否则编译器是无法知道是在使用类型,还是类的成员(因为类的静态成员的使用方法也是T::xxx,这跟某个类中的类型的使用方法是一样的)。

        下面看一下简单的例子:

#include 
#include 

struct myData
{
    typedef unsigned int myType;
    myType mValue;

    myData()
    {
       mValue = 100; 
    }
};

template 
int func(const T &it)
{
    T::myType value = 200;
    return it.mValue - value;
}

int main()
{
    myData data;
    myData::myType ret = func(data);
    printf("ret = %d\n", ret);
}

在这个模板函数 func 中想要使用 myData::myType 这个类型来声明一个变量 value,这样编译会出现什么错误呢?

模板中的依赖类型使用 --- typename_第1张图片

编译错误已经指明,需要使用 typename 来引用T::myType 这个类型,因为T是一个依赖作用域。假如不用 typename 也能编译成功的话,是不是就会产生歧义了?因为 T::myType 也可以表示为一个类的静态成员,所以 typename 是必要的。 所以要想使用依赖于模板参数的类型时,必须加上 typename,如:typename T::myType value = 200;

如《Effective STL》中的例子
 

template
bool lastGreaterThanFirst(const C& container)
{
    if (container.empty()) return false;
    typename C::const_iterator begin(container, begin());
    typename C::const_ierator end(container.end());
    return *--end > *begin;
}

在这个例子里,局部变量begin和end的类型是C::const_iterator。const_iterator是依赖形式类型参数C的一种类型。因为C::const_iterator是一种依赖类型,你被要求在它之前放上 typename 这个词。(一些编译器错误地接受没有typename的代码,但这样的代码不可移植。)

你可能感兴趣的:(#,template--模板,c++)