为什么 c++ 模板参数应声明为类类型
Why c++ template parameters should be declared as class type?
函数模板的语法
template <**class** T, ...>
returntype functionname(arguments)
{
.....
.....
}
我有两个问题?
- 为什么模板参数应该声明为类类型?(即使用类关键字)
- 当我们将其声明为类类型时,编译器是什么东西会吗?
template
参数中使用class
引起的常见混淆。
class
的事情与类无关;它只是说模板接受类型模板参数(而不是整数1 模板参数),它可以是任何类型,而不仅仅是类。
那么,他们为什么选择class
呢?因为他们必须使用一个在任何C++程序中肯定没有使用的关键字,并且或多或少"听起来不错"——class
没关系,因为它在C++中已经是一个保留的关键字。
请注意,class
还有一个替代方法:typename
关键字。它们是完全等价的2,但在我看来typename
更清楚,因为名称只是说"后面是一个类型参数",而不会让你认为它一定是一个类。
为什么两种语法都允许?因为 typename
关键字后来确实在语言中引入(当他们注意到有必要添加另一个关键字来消除模板中的某些声明的歧义时);然后,它也被"改造"用于template
论证声明。保留了 class
关键字的这种用法,以便与同时编写的程序/文档兼容。
- 为了简单起见,我在这里说"积分",显然我指的是一般的非类型模板参数(C++11,§14.1 ¶4)。
模板参数中的类和类型名之间没有语义差异。
(C++11, §14.1 ¶2)
因为这是语言定义告诉你使用的词。 在此上下文中,"类 T"表示"T 是某种类型的名称",而不是"T 是某个类的名称"。
我认为理由在于不希望再添加另一个保留词。
然而,该语言最终添加了另一个保留词:你可以等价地说"typename T"。
根据标准,有两个关键字:class
和typename
。您可以在模板定义中使用其中任何一个。两者具有相同的含义:当您在模板定义中编写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
- std::enable_if 更改成员 *变量* 声明/类型
- 对前向声明类型进行unique_ptr的解决方法
- 如何将声明类型作为参数发送
- 在 Fortran 中泛化特定声明类型的操作
- 使用 (c++11) 声明类型时放置 __declspec(dllimport) 关键字的位置
- 模板函数可以使用带有删除的构造函数的声明类型
- 声明类型没有任何可变类型
- 如何使用声明类型简化此代码
- 使用声明类型选择函数专业化
- 替代班级内声明类型的别名
- 对于自动键入推论的参数,声明类型(自动)应推导的内容
- 使用 decltype 的条件声明类型
- 您如何声明类型结构的堆栈?在C 中
- 将指向前向声明类型的指针推送到 typedef'd 向量时出现编译器错误
- 声明适用于 auto,但不能显式声明类型?
- 声明类型包含未展开的参数包'Args'
- 课堂上的Typedef.在另一个类错误中:尚未声明类型
- 冲突的声明类型/价值不匹配
- 获取具有AST访问者clang的功能声明类型
- 变量声明类型定义 C 中的约定