Posted on 2007-05-31 14:45
chemz 阅读(2161)
评论(6) 编辑 收藏 引用 所属分类:
C++
什么是concept
在范型程序设计领域有一个必须要掌握的名词“concept”,中文翻译叫做“概念”,这个
翻译仅仅是一个concept英文的直译,并没有包含范型程序设计中concept的特定含义,要想
真正的进入到范型程序设计领域,理解范型设计的思想,首先必须完全弄明白什么是concept?
在《美国传统词典[双解]》中,concept这一名词被解释为:
1. A general idea derived or inferred from specific instances or occurrences.
概念:从特定情形或事件中得到或推断出的一般性想法
2. Something formed in the mind; a thought or notion.See Synonyms at idea.
想法:在脑海中形成的想法;思想或观念参见 idea
3. Usage Problem A scheme; a plan.
设想;计划
在范型程序设计的发源地SGI,在STL_DOC中有对什么是concept的专门的描述:
“One very important question to ask about any template function, not just
about STL algorithms, is what the set of types is that may correctly be
substituted for the formal template parameters. Clearly, for example,
int* or double* may be substituted for find's formal template parameter
InputIterator. Equally clearly, int or double may not: find uses the
expression *first, and the dereference operator makes no sense for an
object of type int or of type double. The basic answer, then, is that
find implicitly defines a set of requirements on types, and that it may
be instantiated with any type that satisfies those requirements. Whatever
type is substituted for InputIterator must provide certain operations: it
must be possible to compare two objects of that type for equality, it must
be possible to increment an object of that type, it must be possible to
dereference an object of that type to obtain the object that it points to,
and so on.
Find isn't the only STL algorithm that has such a set of requirements; the
arguments to for_each and count, and other algorithms, must satisfy the same
requirements. These requirements are sufficiently important that we give them
a name: we call such a set of type requirements a concept, and we call this
particular concept Input Iterator. We say that a type conforms to a concept,
or that it is a model of a concept, if it satisfies all of those requirements.
We say that int* is a model of Input Iterator because int* provides all of the
operations that are specified by the Input Iterator requirements.
Concepts are not a part of the C++ language; there is no way to declare a
concept in a program, or to declare that a particular type is a model of a
concept. Nevertheless, concepts are an extremely important part of the STL.
Using concepts makes it possible to write programs that cleanly separate
interface from implementation: the author of find only has to consider the
interface specified by the concept Input Iterator, rather than the
implementation of every possible type that conforms to that concept. Similarly,
if you want to use find, you need only to ensure that the arguments you pass
to it are models of Input Iterator. This is the reason why find and reverse
can be used with lists, vectors, C arrays, and many other types: programming
in terms of concepts, rather than in terms of specific types, makes it possible
to reuse software components and to combine components together. ”
侯捷在《Genericity/STL 大系》一文中将concept解释为:(此处和SGI的说法吻合)
“所谓 concept,描述某个抽象型别的条件(或说需求,requirements)。concept 并
不是一个 class,也不是一个变数或是一个 template 叁数;C++ 语言之中没有任何东
西可以直接代表一个concept。然而,在每一个用到泛型程式设计方法的 C++ 程式中,
concept 非常重要。由 concepts 所构成的阶层体系,正是 STL 的主体结构。
当某个型别满足某个 concept 的所有条件,我们便说此型别是该 conecpt 的一个model。
concept 可被视为一组型别条件。如果型别 T 是 concept C 的一个 model,那麽 T 就
一定满足 C 的所有条件。因此,concept 亦可被视为是一组型别。如果型别 T 是
concept C 的一个 model,我们便可说 T 隶属於「C 所表现的一组型别」”
由上面的三种不同角度的解释可以看出来,concept实际上应该是一个人在认识一种事物
或现象的过程中总结或抽象出来的一种思想和设计,而由于人类在认知事物、现象和世界时
均带有自身的约束和局限,那么就决定了总结或抽象出来的思想和设计都具有一定的约束和
局限,或者叫做具有一定的边界(范围)。那么在人们利用这些思想或设计重新审视一种
事物或现象时,就会在这种思想和设计的边界之内来进行判断,在这个范围内的我们称之为
符合这种概念,那么如何判断一种事物或现象是否符合某个概念呢?一般情况下必须在这个
concept下形成特殊的判断条件,这些条件组合起来完成了一种concept和另外一种concept
之间的区别,也就是条件的集合称为了判断一种事物或现象是否归属于某一个concept的依据。
当然,不同的concept之间可能会有交集,但绝对不会完全重合。
上面是一种一般性的极度抽象的解释concept的方法,在将这种解释应用到某一个实际的
真实环境或领域时应该是如何的呢?我们需要给这个concept指定一个名称,用于表示这个
concept,同时我们还必须确定这个用于判断一种事物或现象是否归属于这个concept的条件
,进而形成concept的判断边界(范围,集合)。那么在范型程序设计中的concept就非常好
理解了,比如:Iterator这样的一种concept,同样是在人们的程序设计过程中为了完成对
容器对象中的元素进行访问,而抽象和总结出来的处理类似问题域的一种思想或设计,那么
经过更进一步的设计和构想,就会逐渐的将什么才能够算得上是一个iterator的判断依据
确定下来,形成Iterator这一concept的边界,也就是他形成了一些用于鉴别一个实例是否
归属于一个concept范畴的条件集合(约束集),在软件中这实际上就是一个实例必须具备
concept所定义的接口形式和语义(包括编译时和运行时),在Iterator概念中就必须明确
的要求一个实例必须提供类似于++、--、*、==、!=等等这样的接口形式和每一种接口所代
表的语义,要注意形式和语义是缺一不可的,必须严格的符合,否则就不能够算是符合某一
个concept。
其实concept就是这些东西,上面的解释过于形式化,不太好理解。因为不是每一个都能
很好的仅仅通过形式化的定义理解一个concept的形成条件、最初的问题域、和提出者的思想
的(也就和一个代数公式一样,必须要在他所形成和适用的环境中才能够较容易的理解),这
样一来,人们会在concept形式化的描述中添加一些该concept最初的问题域的描述、形成时
提出者的思想和初衷想法等,以帮助理解这个concept,所以就形成了STL_DOC和侯捷等其他人
的有关concept就是一组需求的解释,其实STL_DOC的解释更为全面和准确。