限定依赖类型的类型定义

typedef for qualified dependent types

本文关键字:类型 定义 依赖      更新时间:2023-10-16

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

你的第二个假设是错误的。Inner2 确实依赖于 T,因为每个 Outer 都有另一个 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); 
};

Outer<T>::Inner2确实依赖于类型T,因为编译器不知道Inner2是什么东西 - 无论是类型还是静态数据成员。 所以是的,你需要通过在这里使用typename告诉编译器它是什么样的东西,因为默认值是假设它是一个非类型成员(例如静态数据成员、方法名称、enum值)。

(对于C++03来说也是如此 - 我假设这方面的规则在C++11中没有改变。