我读了很多关于如何使用C ++中的typename关键字的摘要:http://pages.cs.wisc.edu/~driscoll/typename.html
我仍然想知道一个特定的例子:
template<typename T> class Outer{
public:
class Inner1{
T t;
};
class Inner2{
int t;
};
};
template<typename T> void foobar(void)
{
std::list<Outer<T>::Inner1> l;
}
从上面链接的文字我明白我需要
std::list<typename Outer<T>::Inner1> l;
因为Inner1既合格又依赖。
但是:Inner2还需要一个让我困惑的类型名称: 首先,似乎很清楚Inner2是一种类型(嗯,对于Inner1来说已经很清楚了)。其次,Inner2根本不依赖于T.对于所有可能的Ts,Inner2将是相同的(类型)!
我在模板中使用合格类型时是否需要typedef?是否取决于模板参数?
答案 0 :(得分:3)
你的第二个假设是错误的。 Inner2 依赖于T,因为每个外部都有另一个Inner2。如果你专注于Outer,那就很清楚了:
template<> class Outer<char>{
public:
class Inner1{
T t;
};
typedef int Inner2;
};
即使您没有专业化,Outer<float>::Inner2
和Outer<long>::Inner2
可能具有相同的布局,成员,名称等,但它们的类型不同!考虑访问权限 - Outer<long>::Inner2
可以访问Outer<long>
的私人成员,Outer<float>::Inner2
没有。
在以下专业化中,Inner2甚至不是一个类型:
template<> class Outer<long double>{
public:
char Inner2(int);
};
答案 1 :(得分:1)
Outer<T>::Inner2
确实取决于类型T
,因为编译器不知道Inner2
是什么类型的东西 - 无论是类型还是例如静态数据成员。所以是的,你需要在这里使用typename
告诉编译器它是什么类型的东西,因为默认是假设它是非类型成员(例如静态数据成员,方法名称, enum
值。)
(C ++ 03也是如此 - 我假设C ++ 11中的规则没有改变。)