介绍
Generic programming is about generalizing software components so that they can be easily reused in a wide variety of situations. In C

,

and function templates are particularly effective mechanisms for generic programming because they make the generalization possible without sacr

icing efficiency.
泛型编程是有关

般化(generalizing)软件Software组件使得他们那可以在广泛

情况下得到重用

编程技术

在C

中

类和

模板对泛型编程是尤其有效率

机制

他们在无需牺牲效率

情况下实现这种

般化(generalizing)
As a simple example of generic programming, we will look at how _disibledevent=>const char* last = ((const char*)region2) + n;
char* result = (char*)region1;
while (first != last)
*result

= *first

;

result;
}
The memcpy

function is already generalized to some extent by the use of void* so that the function can be used to copy

.gif' />s of d

ferent kinds of data. But what

the data we would like to copy is not in an

.gif' />? Perhaps it is in a linked list. Can we generalize the notion of copy to any sequence of elements? Looking at the body of memcpy

, the function's minimal requirements are that it needs to to traverse through the sequence using some sort of po

er, access elements po

ed to, write the elements to the destination, and compare po

ers to know when to stop. The C

standard library groups requirements such as these

o concepts, in this

the Input Iterator concept (for region2) and the Output Iterator concept (for region1).
memcpy

已经在某种程度上通过void*

使用实现了

般化


可以用来拷贝任何类型数据



但是如果我们想要拷贝

数据不在

个

中呢?可能它在

个链表中

我们可以

般化拷贝任何元素序列这个概念吗?看看memcpy


体


所需要

最低要求是使用某种指针遍历序列

存取指向

元素

并比较指针来得知何时停止

C

标准库把类似这样

需求归类为概念

在这例中是

Input Iterator概念Output Iterator概念
If we rewrite the memcpy

as a function template, and use the Input Iterator and Output Iterator concepts to describe the requirements _disibledevent=>*result

= *first

;

result;
}
Using the generic copy

function, we can now copy elements from any kind of sequence, including a linked list that exports iterators such as std::list.
使用泛型

copy


我们现在可以拷贝来自任何种类

序列

元素

包括提供了iterators

链表

像std::list
#

<list>
#

<vector>
#

<iostream>

{
const

N = 3;
std::vector<

> region1(N);
std::list<

> region2;
region2.push_back(1);
region2.push_back(0);
region2.push_back(3);
std::copy(region2.begin

, region2.end

, region1.begin

);
for (

i = 0; i < N;

i)
std::cout << region1[i] << " ";
std::cout << std::endl;
}
--------------------------------------------------------------------------------
Anatomy of a Concept
概念剖析
A concept is a

requirements, where the requirements consist of valid expressions, associated types, invariants, and complexity guarantees. A type that satisfies the

of requirements is said to model the concept. A concept can extend the requirements of another concept, which is called refinement.

个概念是数个要求(requirements)

集合

其中要求包括有效

表达式

相关

类型

不变量

和复杂度

保证


个满足这样

套要求

类型被称为模塑这个概念


个概念可以扩展另外

个概念

要求

这个称为refinement
Valid Expressions are C

expressions which must compile successfully for the objects involved in the expression to be considered models of the concept.
有效

表达式是必须成功编译

C

表达式

对于表达式中包括

对象称为概念

模型
Associated Types are types that are related to the modeling type in that they participate in _disibledevent=>
Invariants are run-time characteristics of the objects that must always be true, that is, the functions involving the objects must preserve these characteristics. The invariants often take the form of pre-conditions and post-conditions.
不变量是对象运行时

性质

必须永远为真

也就是说

对象中


必须保有这些性质

不变量经常以pre-condition和post-condition

形式出现
Complexity Guarantees are maximum limits _disibledevent=>

个经常和traits类并用

技术是tag dispatching

它是

种使用

重载来分派

基于同

属性

区别类型

这项技术


个很好哦实现是C

标准

库中

std::advance


它使

个迭代器步进n次

根据迭代器

种类

可以对迭代器施以区别

优化

如果迭代器是random access(可以向前和向后跳跃任意距离)

那么advance

可以简单

用i

n来实现

而且是非常有效率

:常量时间

其他

迭代器必须分n步前进

使得操作表现为线性


如果迭代器是bidirectional

那么它使得n可以为负数

因此我们必须决定是否使迭代器步进或者步退
The relation between tag dispatching and traits

es is that the property used for dispatching (in this

the iterator_category) is often accessed through a traits

. The

advance

function uses the iterator_traits

to get the iterator_category. It then makes a call the the overloaded advance_dispatch

function. The appropriate advance_dispatch

is selected by the compiler based _disibledevent=>
tag dispatching和traits类的间

关系是用来分派


属性(在此例中是iterator_category)经常由

个traits类来取得

advance


主

使用iterator_traits类来获得iterator_category

然后它


个重载了

advance_dispatch

由编译器根据iterator_category解析(resolve)为

类型来决定具体

重载版本

iterator_category要么是input_iterator_tag要么是bidirectional_iterator_tag要么是random_access_iterator_tag

tag是

个仅仅用来传达tag dispatching或者类似技术中用到


些属性

类

参考这个页面来获得有关iterator tags

更具体

描述

std {
struct input_iterator_tag { };
struct bidirectional_iterator_tag { };
struct random_access_iterator_tag { };

detail {
template <

InputIterator,

Distance>
void advance_dispatch(InputIterator& i, Distance n, input_iterator_tag) {
while (n--)

i;
}
template <

BidirectionalIterator,

Distance>
void advance_dispatch(BidirectionalIterator& i, Distance n,
bidirectional_iterator_tag) {

(n >= 0)
while (n--)

i;
while (n

) --i;
}
template <

RandomAccessIterator,

Distance>
void advance_dispatch(RandomAccessIterator& i, Distance n,
random_access_iterator_tag) {
i

n;
}
}
template <

InputIterator,

Distance>
void advance(InputIterator& i, Distance n) {
typename iterator_traits<InputIterator>::iterator_category category;
detail::advance_dispatch(i, n, category);
}
}
--------------------------------------------------------------------------------
Adaptors
配接器
An adaptor is a

template which builds _disibledevent=>

Reference = complicated default,

Po

er = complicated default,

Category = complicated default,

Distance = complicated default
>
struct filter_iterator_generator {
typedef iterator_adaptor<
Iterator,filter_iterator_policies<Predicate,Iterator>,
Value,Reference,Po

er,Category,Distance> type;
};
Now, that's complicated, but producing an adapted filter iterator is much easier. You can usually just write:
现在

虽然generator本身是复杂

但是创建

个配接了

filter iterator更加容易了

你通常可以仅仅这么写:
boost::filter_iterator_generator<my_predicate,my_base_iterator>::type
--------------------------------------------------------------------------------
Object Generators
An object generator is a function template whose _disibledevent=>
For example, given:
例如

给出:
struct widget {
void tweak(

);
};
std::vector<widget *> widget_ptrs;
By chaining two standard object generators, std::bind2nd

and std::mem_fun

, we can easily tweak all widgets:
通过把两个标准object generator

std::bind2nd和std::mem_fun

链在

块

我们可以轻易地拧上所有

widgets:
void tweak_all_widgets1(

arg)
{
for_each(widget_ptrs.begin

, widget_ptrs.end

,
bind2nd(std::mem_fun(&widget::tweak), arg));
}
Without using object generators the example above would look like this:
不使用object generator

上面

例子可能看上去是这样:
void tweak_all_widgets2(

arg)
{
for_each(struct_ptrs.begin

, struct_ptrs.end

,
std::binder2nd<std::mem_fun1_t<void, widget,

> >(
std::mem_fun1_t<void, widget,

>(&widget::tweak), arg));
}
As expressions get more complicated the need to reduce the verbosity of type spec

ication gets more compelling.
当表达式变得更加复杂

减轻类型介绍说明

冗长

要求变得更加迫切
--------------------------------------------------------------------------------
Policy Classes
A policy

is a template parameter used to transmit behavior. An example from the standard library is std::allocator, which supplies memory management behaviors to standard containers.

个policy类时

个用来传播行为

模板参数

来自标准库


个例子是std::allocator

它给标准容器提供内存管理

行为
Policy

es have been explored in detail by Andrei Alexandrescu in this paper. He writes:
policy类在Andrei Alexandrescu

这篇文章中被深度探究

他写道:
Policy

es are implementations of punctual design choices. They are inherited from, or contained within, other

es. They provide d

ferent strategies under the same syntactic

erface. A

using policies is templated having one template parameter for each policy it uses. This allows the user to select the policies needed.
policy类是严格设计


个是实现

他们从其他类继承或者包含于其他类

他们在同样

句法接口

基础上提供区别

策略


个使用策略

类为每个它使用

策略提供

个模板参数

这使得用户选择他们需要

策略
The power of policy

es comes from their ability to combine freely. By combining several policy

es in a template

with multiple parameters, one achieves combinatorial behaviors with a linear amount of code.
policy类

威力来自于他们自由组合

能力

通过在

个模板类中用多个参

合好几个policy类

实现了在线性数量

代码中提供组合

行为
Andrei's description of policy

es describe their power as being derived from their granularity and orthogonality. Boost has probably diluted the distinction in the Iterator Adaptors library, where we transmit all of an adapted iterator's behavior in a single policy

. There is precedent for this, however: std::char_traits, despite its name, acts as a policies

that determines the behaviors of std::basic_

.
Andrei对于policy类

描述介绍说明他们

威力来自于他们

颗粒性和正交性

Boost可能已经冲淡了在Iterator Adaptor库中

区别

我们在

个policy类中传播所有adapted iterator

行为

然而这有

个先例:std::char_traits

不管它

名字

就像

个policy


样行为决定std::basic_


行为