1、在template模板定义中,使用关键字class来引导类型T(当然,任何合法的标识符号都可以拿来当作参数名称,例如Type, U等。但通常以T表示,这差不多成了一个“准”标准)。
2、据称最开始使用class是为了避免增加新的关键词。然而最终还是不得不引入一个新的关键词typename。
3、当引用类型T的内部类型(inner type)时, 必须使用关键字typename。例如:
template <class T>
class MyClass {
public:
typename T::SubType *ptr; // SubType 是T的一个内部类型,这里的typename 必不可少!
....
};
以上代码中的typename必不可少。否则,T::SubType 会被视为T的一个static成员变量。
此外,SubType 成为一个类型的必要条件是:任何一个用来取代T的类型,其内部必须提供了一个内部类型(inner type)SubType 的定义。
MyClass<Q> x;
则必须有:
class Q {
public:
typedef int SubType;
.....
};
SubType 也可以是抽象数据类型:
class Q {
public:
class SubType;
.....
};
4、C++标准规定:除了以typename修饰之外,template内的任何标识符号都被视为一个值(value)而非一个类型(type).
问题:以class修饰不行么?
我试验的结果是:当SubType是类(class)类型时,行! 当SubType是内建的(bulti-in)基本数据类型时,则不行!
5、实验代码如下:
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
// class Age
// {
// public:
// explicit Age(int value) : itsValue(value)
// {
// }
// int itsValue;
// };
typedef int Age;
typedef std::string Name;
explicit Person(const Name &name, const Age &age) : m_name(name), m_age(age)
{
}
std::string name() const
{
return m_name;
}
void setName(const std::string &name)
{
m_name = name;
}
Age age() const
{
return m_age;
}
void setAge(const Age &age)
{
m_age = age;
}
private:
Name m_name;
Age m_age;
};
template <class T>
void printInfo(const T &t)
{
/*typename*/ class T::Name myName = t.name();
typename /*class*/ T::Age myAge = t.age();
cout << "myName=" << myName;
cout << " myAge=" << myAge;
//cout << " myAge=" << myAge.itsValue;
}
int main()
{
cout << "Hello World!" << endl;
Person Obama("Obama", Person::Age(54));
printInfo<Person>(Obama);
return 0;
}