4

我正在阅读主题泛型类。我被卡在了一点上。以下是一段代码

template <class StackType> class stack
{
    StackType stck[10];
    int tos;
public:
    stack() {tos=0;}
    void push(StackType ob);
    StackType pop();
};

我的问题是template <class StackType> class stack,有两个类(StackTypestack)?

我的意思是编译器如何将其视为使堆栈成为 StackType 的嵌套类或其他东西?

4

5 回答 5

8

它不是创建第二个类,而是创建一个 Stack 类型的类,其中 StackType 被用户给定的类型所取代。定义它的更好方法是使用 typename(第 14.1.2 节),这样可以更清楚地了解实际发生的情况。有关模板的更多信息,请参阅C++ 模板

您所描述的是模板中的嵌套类:

template <typename Type>
class Stack
{
public:
    class InnerType
    {
    };
};

在此示例中,InnerType 是一个强名称为 的类Stack<Type>::InnerType,它是基于提供的类型的特定类。因此,如果在代码中的某个地方创建了一个对象,如下所示:

auto x = new Stack<int>();

Stack<int>::InnerType那么将存在一类类型。模板类仅在代码中使用时才存在于程序集中,因此如果没有实现任何变体的对象Stack,则InnerType(任何模板类型的)将不存在。

关于声明模板的更多细节也在 SO 上讨论

于 2013-09-20T19:33:22.790 回答
3

没有二等舱。StackType是模板参数。您可以像考虑带有一个参数的函数的参数一样来考虑它。除非被调用并提供它的参数,否则该函数不能做任何事情。与模板类相同StackType,它是模板类型的类型参数stack。当您将 type[name] 作为参数提供给模板类时,您将专门化模板类。所有这些参数提供和专业化都发生在编译时。例如,当编译器第一次遇到类似

堆栈<int>堆栈变量;

或者

typedef 堆栈<int> StackOfInts;

只有这样它才会真正编译并实例化一个名为的类型stack< int >- 一个整数堆栈。在那一刻之前,没有任何东西堆积。

用你的类实例化后int变成:

template<>
class stack< int >
{
  int stck[10];
  int tos;
public:
  stack() {tos=0;}
  void push(int ob);
  int pop();
};
于 2013-09-20T19:48:31.267 回答
2

class<>外是不同的意思。它本质上与typename.

于 2013-09-20T19:32:33.557 回答
2

所以模板不是一个类。它是模板从用户定义的类型(例如 int)创建类的一种方式。所以当我说:

stack<int>

编译器从您的类生成一个类stack < int >,本质上是填充StackTypeint编译该类。

所以如果我做一个:

stack<stack<int> >

编译器将生成两个类stact < int > stack < stack < int > >

于 2013-09-20T19:35:03.113 回答
1

模板创建了一系列类——它们中的每一个都具有相同的功能,但在不同的类型上运行。

在您的示例中,它正在创建一个类族。例如 X 类堆栈、Y 类堆栈等。

于 2013-09-20T19:38:34.267 回答