typedef用于限定依赖类型

时间:2012-12-05 09:34:08

标签: c++ templates types typename

我读了很多关于如何使用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?是否取决于模板参数?

2 个答案:

答案 0 :(得分:3)

你的第二个假设是错误的。 Inner2 依赖于T,因为每个外部都有另一个Inner2。如果你专注于Outer,那就很清楚了:

template<> class Outer<char>{
public:
  class Inner1{
     T t; 
  };
  typedef int Inner2; 
};

即使您没有专业化,Outer<float>::Inner2Outer<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中的规则没有改变。)