2

我正在查看C++ FAQ上的 C++ 模板部分,并遇到了这个示例(代码不编译)关于使用父模板类的非依赖嵌套类作为子类中的成员

template<typename T>
class B {
public:
  class Xyz { ... };  ← type nested in class B<T>
  typedef int Pqr;    ← type nested in class B<T>
};

template<typename T>
class D : public B<T> {
public:
  void g()
  {
    Xyz x;  ← bad (even though some compilers erroneously (temporarily?) accept it)
    Pqr y;  ← bad (even though some compilers erroneously (temporarily?) accept it)
  }
};

C++ 常见问题解答 35.18

不幸的是,这也不起作用,因为这些名字(你准备好了吗?你坐下吗?)不一定是类型。“啊?!?” 你说。“不是类型?!?” 你惊呼。“这太疯狂了;任何傻瓜都可以看出他们是类型;看看!!!” 你抗议。抱歉,事实是它们可能不是类型。原因是 B 可以有一个特化,例如 B,其中 B::Xyz 是一个数据成员。由于这种潜在的特化,编译器在知道 T 之前不能假定 B::Xyz 是一个类型。解决方案是通过 typename 关键字给编译器一个提示:

所以作者说there can be a specialization of B<T>, say B<Foo>, where B<Foo>::Xyz is a data member, for example.。这是我不太了解的部分——如何专门化一个模板类(不从它继承)向该类添加另一个成员,在另一个专门化(例如B<Baz>)中不存在?当然,这是假设D's static if之类的东西不存在。

我错过了什么吗?

4

1 回答 1

4

当您显式特化类模板时,您正在为给定的模板参数重新定义类。这是一个简单的例子:

template <typename T>
struct foo
{
  typedef T type;
};

template <>
struct foo<int>
{
  static int type;
};

现在,如果我foo使用除 之外的任何其他模板参数来实例化 a int,那么该成员type就是一个类型。否则,它是一个int数据成员。

于 2013-04-03T15:58:33.210 回答