【发布时间】:2022-01-03 11:25:39
【问题描述】:
模板类和类模板有什么区别?
【问题讨论】:
标签: c++
模板类和类模板有什么区别?
【问题讨论】:
标签: c++
模板类与Template Method design pattern相关,而类模板只是一个“填空”类模板。
【讨论】:
这对于许多人来说是一个常见的混淆点(包括 Wikipedia 上的通用编程页面、一些 C++ 教程以及此页面上的其他答案)。就 C++ 而言,没有“模板类”之类的东西,只有“类模板”。阅读该短语的方式是“类的模板”。与“函数模板”相反,“函数模板”是“函数的模板”。 再次重申:类不定义模板,模板定义类(和函数)。例如,这是一个模板,具体来说是一个类模板,但它不是一个类: p>
template<typename T> class MyClassTemplate
{
...
};
声明MyClassTemplate<int> 是一个类,或者学究式地说,是一个基于模板的类。 基于模板的类与不基于模板的类没有特殊属性。特殊属性是模板本身的。
短语“模板类”没有任何意义,因为就 C++ 而言,“模板”一词在应用于名词“类”时作为形容词没有任何意义。它意味着存在一个class,它是(或定义)一个模板,这在C++中是不存在的概念。
我理解常见的混淆,因为这可能是基于单词在实际语言中以“模板类”的顺序出现的事实,这是另一回事。
【讨论】:
不同之处在于 C++ 标准中根本不存在术语“模板类”。这是一个主要由认为“类模板”一词令人困惑的人使用的术语(如 Qt 公司诺基亚和以前的 Trolltech)。
标准没有它的概念,所以要由其他人来做出改变。有些人将其用作同义词,而另一些人则说术语“模板类”指的是实例化或明确专门化的类模板,这使其等同于术语“类模板专业化”。从历史上看,它有这个含义。 Annotated Reference Manual 在第 343 页定义
从类模板生成的类称为模板类,正如专门定义的以 template-class-name 作为其名称的类
非终端 template-class-name 等同于当今标准中使用的非终端 template-id,并归结为 template-name < arguments >。
让您熟悉今天的术语,这比使用可疑的旧术语更重要
// (1) defines a class template
template<typename T> class A { };
// (2) defines a class template explicit specialization
template<> class A<int> { };
// (3) defines a class template partial specialization
template<typename T> class A<T*> { };
// (4) explicitly instantiates A<char>.
template class A<char>;
// (5) implicitly instantiates A<short> (because of the member declaration)
struct D { A<short> a; };
【讨论】:
模板类:具有通用定义的类或具有参数的类,在客户端提供信息之前不会实例化。它被称为普通模板的行话。带有前缀模板和使用 T 的简单类。类模板:类的单个构造由类模板指定,这与使用类构造单个对象的方式几乎相似。引用模板类Ex-classname objectname(argument list)的一个对象
【讨论】:
类模板是不同类型对象的通用类。基本上,它提供了基于参数生成类的规范。每当创建一个新对象时,都会在内存中为此目的创建一个新类。这称为实例化类模板,类的每个实例化版本称为模板类。
【讨论】:
C++ 的创造者 Bjarne Stroustrup 在他的书C++ 编程语言第 4 版中说,23.2.1 定义模板:
有些人对术语 class template 和 template class 进行语义区分。我不;那太微妙了:请考虑这些术语可以互换。同样,我认为 function template 可以与 template function 互换。
【讨论】:
类模板是用于生成类的模板,而模板类是由模板生成的类。
【讨论】:
看看this paper(from wg21 and was published in 1992):
一致的术语
迄今为止,大部分争论和分歧都与描述模板的章节中使用的术语有关。最常见的是 'function-template' 和 'template-function' 的不同应用来表达不同的想法和意图。由于没有应用一致的命名,结果是混乱和争论。
就本文档而言,作为委员会在讨论模板时正式采纳的提案,并用于澄清文档;我建议我们采用形式化,即 尾随 '-template' 描述由模板描述的一组类型或函数。而那个前导'template-',用来描述'-template'的一部分的模板定义,例如
'template-member-function'。因此:-
- 'function-template':模板描述的一组函数,参数化了作为参数提供给该模板的某些类型信息。 例如:-
template<class T> int nullcheck( T* pT )
{ return ( pT != 0 ); }
- 'class-template':由模板描述的一组类,参数化某些类型信息作为该模板的参数。为了 示例:-
template<class T> class S {
int i;
public:
int sep_member();
int imm_member()
{ return 2; }
}
- 'template-function':不再允许使用该术语。**
'template-class':这个词是不允许的。**
'member-function-template': 不允许使用该术语,因为它描述了模板定义当前不支持的属性。使用 上面的术语约定,这将描述一个成员 一个非类模板,它的定义本身就是一个 模板。例如:-
class Normal { public:
template<class T> int foo(T*pT)
{ return ( pT == 0 ); }
};
但是,由于模板目前仅限于全局 范围,这样的模板无效。
- '模板静态成员函数':
- '模板成员函数':
- '模板静态成员':
- '模板静态数据成员 '模板成员': 出现的成员定义的替代术语 与其所属的“类模板”分开。为了 示例:-
template<class T> int S<T>::sep_member()
{ return i; }
【讨论】:
Normal 类:我不知道这样的 member-function-template 是被禁止的。我尝试过的所有编译器都接受它。我错过了什么?