C++中“概念”(concept)之含义
先考虑一个模板函数templatetypename Seq, typename Value Value sum(Seq s, Value v) { for (const auto x : s) vx; return v; }这个模板函数sum要求(1) 它的第一个模板参数是某种元素序列并且(2) 它的第二个模板参数是某种数因为要进行加法运算。更具体地讲必须使用一对参数调用sum:一个序列 Seq支持 begin() 和 end()以便可以使用范围 for 进行遍历。一种支持 运算符的算术类型 Value以便可以对序列中的元素进行加法运算。我们把这样的要求称为概念(concepts)(即符合要求的表述对象称为概念这些表述对象可以转化为代码可以用不同的代码实现)。满足这种简化后的序列 (也称为范围) 要求以及更多要求的类型示例包括标准库中的 vector、list 和 map。满足这种简化后的算术类型要求以及更多要求的类型示例包括 int、double 和 Matrix对于任何合理的 Matrix 定义。我们可以说 sum() 算法在两个维度上是通用的用于存储元素的数据结构类型“序列”和元素的类型。概念(concepts)不是任意的属性集合。大多数类型(或一组类型)的属性列表都没有定义一个连贯且有用的概念。要使作为一个概念有用需求列表必须反映一组算法或一组模板类操作的需求。在许多努力领域人们已经设计或发现了描述该领域基本内涵(concept)的概念(concept) (C 中“concept”一词的技术用法就是考虑到这种常见用法而选择的)。似乎很少有概念是有意义的(译注大概指术语能反映事件的真实含义)。例如代数建立在一元组(monad)、域(field) 和 环(ring) 等概念之上而 STL 依赖于前向迭代器、双向迭代器和随机访问迭代器等概念。在一个领域找到一个新概念是一项重大成就这不是你应该期望每年都做的事情。大多数情况下你通过检查研究领域或应用领域的基础文本来找到概念。(注此段表明概念是指事件的通用内涵。)“concepts”是一个非常笼统的思想在本质上与模板没有任何关系。甚至 KR C [Kernighan,1978] 也有概念即有符号整数类型是编程语言对内存中整数概念的概括。我们对模板参数的要求也是概念(无论如何表达)因此与概念相关的大多数有趣问题都出现在模板的上下文中。(此段指的概念是指对模板参数施加的基本要求。)概念是精心设计的实体反映了应用领域的基本属性。因此应该只有少数概念可以作为算法和类型设计的指导方针。这与物理插件 和插座类似我们希望用最少的插头和插座简化我们的生活并降低设计和建造成本。这种理想可能与每个单独的通用算法和每个单独的参数化类的最低要求理想相冲突。此外这种理想可能与为类提供绝对最小接口的理想相冲突甚至与一些程序员认为他们有权“完全按照自己喜欢的方式”编写代码相冲突。然而如果不付出努力和某种形式的标准我们就无法获得插件兼容性。也就是说概念(符合要求的描述体)应当尽量反映通用性、一定的稳定性、跨多种算法的可用性、语义一致性等等因此概念不等于模板类或函数但是模板类或函数是概念的一种很好的体现。我们希望模板参数的许多简单约束都不符合概念的条件(指通用性的要求)。我们编写的许多模板并不反映通用算法或广泛适用的类型。相反它们是实现细节它们的参数只需反映模板的必要细节该模板的目的在于在某事物的单一实现中一次性使用对此类模板参数的要求为约束或(如果必须)临时概念(不具有通用性的模板参数称为约束或临时概念)。看待约束的一种方法是将它们视为接口的不完整(部分)规范。通常部分规范很有用而且比没有规范要好得多。