【问题标题】:typedef for qualified dependent typestypedef 用于合格的依赖类型
【发布时间】:2025-11-23 06:45:01
【问题描述】:

我阅读了这篇关于 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。对于所有可能的 T,Inner2 将是相同的(类型)!

在模板中使用限定类型后是否需要 typedef?是否依赖于模板参数?

【问题讨论】:

  • For all possible Ts, Inner2 will be the same (type)! - 不,考虑类模板专业化。

标签: c++ templates types typename


【解决方案1】:

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

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

即使你不专攻,Outer&lt;float&gt;::Inner2Outer&lt;long&gt;::Inner2 可能有相同的布局、成员、名称等,但它们不是同一类型!考虑访问 - Outer&lt;long&gt;::Inner2 可以访问 Outer&lt;long&gt; 的私人成员,Outer&lt;float&gt;::Inner2 没有。

在以下特化中,Inner2 甚至不是类型:

template<> class Outer<long double>{
public:
  char Inner2(int); 
};

【讨论】:

  • 没错,我没有考虑专业化!非常感谢!
【解决方案2】:

Outer&lt;T&gt;::Inner2 确实取决于 T 类型,因为编译器不知道 Inner2 是什么类型的东西——无论是类型还是例如静态数据成员。所以是的,你需要在这里通过使用typename 告诉编译器它是什么类型的东西,因为默认是假设它是一个非类型成员(例如一个静态数据成员、一个方法名、一个@987654325 @值)。

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

【讨论】: