为什么 c++ 模板参数应声明为类类型

Why c++ template parameters should be declared as class type?

本文关键字:声明 类型 参数 c++ 为什么      更新时间:2023-10-16

函数模板的语法

template <**class** T, ...>
    returntype functionname(arguments)
    {
           .....
           .....
     }

我有两个问题?

  1. 为什么模板参数应该声明为类类型?(即使用类关键字)
  2. 当我们将其声明为类类型时,编译器是什么东西会吗?
这是在

template参数中使用class引起的常见混淆。

class的事情与类无关;它只是说模板接受类型模板参数(而不是整数1 模板参数),它可以是任何类型,而不仅仅是类。

那么,他们为什么选择class呢?因为他们必须使用一个在任何C++程序中肯定没有使用的关键字,并且或多或少"听起来不错"——class没关系,因为它在C++中已经是一个保留的关键字。

请注意,class还有一个替代方法:typename关键字。它们是完全等价的2,但在我看来typename更清楚,因为名称只是说"后面是一个类型参数",而不会让你认为它一定是一个类。

为什么两种语法都允许?因为 typename 关键字后来确实在语言中引入(当他们注意到有必要添加另一个关键字来消除模板中的某些声明的歧义时);然后,它也被"改造"用于template论证声明。保留了 class 关键字的这种用法,以便与同时编写的程序/文档兼容。

<小时 />
  1. 为了简单起见,我在这里说"积分",显然我指的是一般的非类型模板参数(C++11,§14.1 ¶4)。
  2. 模板参数中的类和类型名之间没有语义差异。

    (C++11, §14.1 ¶2)

因为这是语言定义告诉你使用的词。 在此上下文中,"类 T"表示"T 是某种类型的名称",而不是"T 是某个类的名称"。

我认为理由在于不希望再添加另一个保留词。

然而,该语言最终添加了另一个保留词:你可以等价地说"typename T"。

根据标准,有两个关键字:classtypename。您可以在模板定义中使用其中任何一个。两者具有相同的含义:当您在模板定义中编写class(或typename)时,这意味着模板的用户必须将类型作为模板参数传递给模板;它的意义仅此而已。如果它是一个函数模板,那么模板参数可以(在某些情况下)从参数推导出到函数。

请注意,您可以将标准类型传递给 template ,而不仅仅是类:

template <class T, int N> class mysequence {..};

因此,这里的class关键字告诉编译器将 T 视为类。N 被视为整数。

(1) 为什么要将模板参数声明为类类型?

不完全是真的。您也可以使用typename
:)更重要的是,您可以将某些类型的对象声明const参数。例如

template<int I>  // <---- 'I' is not a class/typename
class A { ... };
...
A<3> obj;

(2)当我们将其声明为类类型时,编译器是什么东西 会吗?

其实不多
但是,编译器会在调用其对象时检查类型是否实际为类型名。例如

template<class T>
class A { ... };  // ok ... not much to check
...
A<int> obj1; // compiler checks if 'int' is a type ---> yes
A<3> obj2; // compiler checks if '3' is a type ---> no