分享
 
 
 

Boost中的范型编程技术

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

H1 {

font-family : "Book Antiqua", "Georgia", "Tahoma", "Times New Roman", "Times", serif;

color : #000000;

font-size : 16pt;

font-weight : bold;

border-width : 0 0 3px;

border-style : double;

border-color : #9f9f9f;

}

H2 {

font-family : "Arial", "Helvetica", sans-serif;

color : #000000;

font-size : 11pt;

font-weight : normal;

background-color : #eeeeee;

padding-left : 4px;

padding-top : 4px;

padding-right : 4px;

padding-bottom : 4px;

border-style : solid;

border-width : 1px;

border-color : #9f9f9f;

text-align : center;

}

H3 {

font-family : "Book Antiqua", "Georgia", "Tahoma", "Times New Roman", "Times", serif;

color : #000000;

font-size : 11pt;

font-weight : bold;

}

body {

margin-left : 10%;

margin-top : 10;

margin-right : 10%;

margin-bottom : 2;

font-family :"Tahoma", "Times New Roman", "Times", serif;

color : #000000;

font-size : 11pt;

scrollbar-face-color: #eeeeee;

scrollbar-shadow-color: #9F9F9F;

scrollbar-highlight-color: #eeeeee;

scrollbar-3dlight-color: #9F9F9F;

scrollbar-darkshadow-color: #FFFFFF;

scrollbar-track-color: #FFFFFF;

scrollbar-arrow-color: #000000;

}

p

{

font-size: 11pt;

color: #000000;

font-family: Georgia, Tahoma, 'Times New Roman' , Times, serif;

}

PRE

{

border-right: #9f9f9f 1pt solid;

border-top: #9f9f9f 1pt solid;

padding-left: 5pt;

padding-bottom: 10pt;

border-left: #9f9f9f 1pt solid;

border-bottom: #9f9f9f 1pt solid;

color: darkblue;

padding-top: 10pt;

font-family: 'Times New Roman';

background-color : #eeeeee;

}

HR

{

color: lightsteelblue;

}

td.general1 {

background-color : #ffcc00;

}

td.general2 {

background-color : #feeec0;

}

td.general3 {

background-color : #DDEEFF;

}

a:link {

color : #1507af;

text-decoration : none;

}

a:visited {

color : #1507af;

text-decoration : none;

}

a:hover {

color : #5547ef;

text-decoration : none;

}

a:active {

color : #4537df;

text-decoration : none;

}

frameset {

border-color : lightsteelblue;

}

这篇文章是boost中文档中取出来的,其实并不是很好,只是已经开始翻译了就索性完成它.结果现在看来很多部分是狗屁不通,哈哈,也就让你们看看在不了解技术本身的情况下的翻译可以多糟糕吧.不要砸我呀.

我的网站:taowen.cn.st

Generic Programming Techniques 范型编程技术

This is an incomplete survey of some of the generic programming techniques used in the boost libraries.

这是对在boost库中使用的某些范型编程技术的不完整的观察。

Table of Contents

目录

Introduction

The Anatomy of a Concept

Traits

Tag Dispatching

Adaptors

Type Generators

Object Generators

Policy Classes

Introduction

介绍

Generic programming is about generalizing software components so that

they can be easily reused in a wide variety of situations. In C++, class

and function templates are particularly effective mechanisms for generic

programming because they make the generalization possible without

sacrificing efficiency.

范型编程是关于一般化(generalizing)软件组件使得他们那可以在广泛的情况下得到重用的编程技术。在C++中,类和函数模板对范型编程是尤其有效率的机制因为他们在无需牺牲效率的情况下实现这种一般化(generalizing)。

As a simple example of generic programming, we will look at how one

might generalize the memcpy() function of the C standard library.

An implementation of memcpy() might look like the following:

作为范型编程的一个简单的例子,我们将来看看如何一般化c标准库中的memcpy函数。memcpy的一个实现可能看上去就像这样:

void* memcpy(void* region1, const void* region2, size_t n)

{

const char* first = (const char*)region2;

const char* last = ((const char*)region2) + n;

char* result = (char*)region1;

while (first != last)

*result++ = *first++;

return result;

}

The memcpy() function is already generalized to some extent by the

use of void* so that the function can be used to copy arrays of

different kinds of data. But what if the data we would like to copy is not

in an array? 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

pointer, access elements pointed to, write the elements to

the destination, and compare pointers to know when to stop. The C++

standard library groups requirements such as these into

concepts, in this case 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 on the template

parameters, we can implement a highly reusable copy() function in

the following way:

如果我们把memcpy重写为一个函数模板,并使用Input Iterator和Output Iterator概念来描述对于模板参数的要求,我们可以用一下方式实现一个有很高重用性的copy函数:

template <typename InputIterator, typename OutputIterator>

OutputIterator

copy(InputIterator first, InputIterator last, OutputIterator result)

{

while (first != last)

*result++ = *first++;

return 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。

#include <list>

#include <vector>

#include <iostream>

int main()

{

const int N = 3;

std::vector<int> region1(N);

std::list<int> region2;

region2.push_back(1);

region2.push_back(0);

region2.push_back(3);

std::copy(region2.begin(), region2.end(), region1.begin());

for (int i = 0; i < N; ++i)

std::cout << region1[i] << " ";

std::cout << std::endl;

}

Anatomy of a Concept

概念剖析

A concept is a set requirements, where the requirements

consist of valid expressions, associated types, invariants, and complexity

guarantees. A type that satisfies the set 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 one or more

of the valid expressions. Typically associated types can be accessed

either through typedefs nested within a class definition for the modeling

type, or they are accessed through a traits class.

相关的类型是和modeling相关的类型,其中的类型在一个或者多个有效的表达式中出现。典型的相关类型既可以通过内蕴在模塑类型的class定义中的typedef也可以通过traits class。

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 on how long the

execution of one of the valid expressions will take, or how much of

various resources its computation will use.

复杂度保证是有效表达式中的一个的执行时间的,或者它计算所消耗的各种资源的多少的最大上限

The concepts used in the C++ Standard Library are documented at the SGI STL site.

在C++标准库中使用的概念在SGI STL 网站上存有文档。

Traits

A traits class provides a way of associating information with a

compile-time entity (a type, integral constant, or address). For example,

the class template std::iterator_traits<T>

looks something like this:

一个traits class提供了一种把信息和一个编译时实体关联起来的方法。例如,类模板std::iterator_traits看上去有些像这样:

template <class Iterator>

struct iterator_traits {

typedef ... iterator_category;

typedef ... value_type;

typedef ... difference_type;

typedef ... pointer;

typedef ... reference;

};

The traits' value_type gives generic code the type which the

iterator is "pointing at", while the iterator_category can be used

to select more efficient algorithms depending on the iterator's

capabilities.

traits的“值类型(value_type)”提供iterator当前指向的类型的范型代码,当“iterator_category”可以被用来根据iterator的能力选择更有效率的算法。

A key feature of traits templates is that they're non-intrusive:

they allow us to associate information with arbitrary types, including

built-in types and types defined in third-party libraries, Normally, traits

are specified for a particular type by (partially) specializing the traits

template.

traits模板的一个关键特性是他们是非插入性的:他们使得我们可以把信息和任意类型关联到一起,包括内建的类型和定义在第三方库中定义的类型,一般的,traits通过(部分)指定traits template来指定用于特定的类型

For an in-depth description of std::iterator_traits, see this page

provided by SGI. Another very different expression of the traits idiom in

the standard is std::numeric_limits<T> which provides

constants describing the range and capabilities of numeric types.

要查看std::iterator_traits的深度描述,参考这个SGI提供的页面。另外一个标准中的traits idiom的非常不同的表达式是std::numeric_limits<T>,它提供了描述数值类型的范围和能力的常数。

Tag Dispatching

A technique that often goes hand in hand with traits classes is tag

dispatching, which is a way of using function overloading to dispatch based

on properties of a type. A good example of this is the implementation of the

std::advance()

function in the C++ Standard Library, which increments an iterator

n times. Depending on the kind of iterator, there are different

optimizations that can be applied in the implementation. If the iterator is

random access (can jump forward and backward arbitrary distances), then the

advance() function can simply be implemented with i += n,

and is very efficient: constant time. Other iterators must be

advanced in steps, making the operation linear in n. If the

iterator is bidirectional,

then it makes sense for n to be negative, so we must decide whether

to increment or decrement the iterator.

一个经常和traits类并用的技术是tag dispatching。它是一种使用函数重载来分派调用基于同一属性的不同类型。这项技术的一个很好哦实现是C++标准函数库中的std::advance函数,它使一个迭代器步进n次。根据迭代器的种类,可以对迭代器施以不同的优化。如果迭代器是random access(可以向前和向后跳跃任意距离),那么advance函数可以简单的用i+=n来实现,而且是非常有效率的:常量时间。其他的迭代器必须分n步前进,使得操作表现为线性的。如果迭代器是bidirectional,那么它使得n可以为负数,因此我们必须决定是否使迭代器步进或者步退。

The relation between tag dispatching and traits classes is that the

property used for dispatching (in this case the iterator_category)

is often accessed through a traits class. The main advance() function

uses the iterator_traits

class 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 on whatever

type the iterator_category resolves to, either input_iterator_tag,

bidirectional_iterator_tag,

or random_access_iterator_tag.

A tag is simply a class whose only purpose is to convey some

property for use in tag dispatching and similar techniques. Refer to this page for a

more detailed description of iterator tags.

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的更具体的描述。

namespace std {

struct input_iterator_tag { };

struct bidirectional_iterator_tag { };

struct random_access_iterator_tag { };

namespace detail {

template <class InputIterator, class Distance>

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

while (n--) ++i;

}

template <class BidirectionalIterator, class Distance>

void advance_dispatch(BidirectionalIterator& i, Distance n,

bidirectional_iterator_tag) {

if (n >= 0)

while (n--) ++i;

else

while (n++) --i;

}

template <class RandomAccessIterator, class Distance>

void advance_dispatch(RandomAccessIterator& i, Distance n,

random_access_iterator_tag) {

i += n;

}

}

template <class InputIterator, class 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 class template which builds on another type or

types to provide a new interface or behavioral variant. Examples of

standard adaptors are std::reverse_iterator,

which adapts an iterator type by reversing its motion upon

increment/decrement, and std::stack, which adapts a

container to provide a simple stack interface.

配接器是一个建立在其他一个类型或者多个类型之上类模板,以提供一个新的接口或者不同的行为。标准配接器的例子是std::reverse_iterator和std::stack。std::reverse_iterator它通过在步增和步退上反转它的运动来配接一个迭代器。std::stack配接一个容器来提供一个简单的栈的接口。

A more comprehensive review of the adaptors in the standard can be found

here.

对于标准中的配接器的一个更深入的评述可以在这里找到

Type Generators

A type generator is a template whose only purpose is to

synthesize a new type or types based on its template argument(s)[1]. The generated type is usually expressed as a nested typedef

named, appropriately type. A type generator is usually used to

consolidate a complicated type expression into a simple one, as in

boost::filter_iterator_generator,

which looks something like this:

type generator是一个仅仅用来基于它的模板参数来合成一个或者多个新的类型的模板。合成的类型经常以嵌套的typedef恰当命名的类型来表示。一个type generator经常用来把一个复杂的类型表达式变成一个简单的东西,就像boost::filter_iterator_generator中的表现的一样。它大概是这样作的:

template <class Predicate, class Iterator,

class Value = complicated default,

class Reference = complicated default,

class Pointer = complicated default,

class Category = complicated default,

class Distance = complicated default

>

struct filter_iterator_generator {

typedef iterator_adaptor<

Iterator,filter_iterator_policies<Predicate,Iterator>,

Value,Reference,Pointer,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 only purpose is

to construct a new object out of its arguments. Think of it as a kind of

generic constructor. An object generator may be more useful than a plain

constructor when the exact type to be generated is difficult or impossible

to express and the result of the generator can be passed directly to a

function rather than stored in a variable. Most Boost object generators are

named with the prefix "make_", after std::make_pair(const T&, const U&).

object generator是一个单纯用来根据它的参数创建对象的函数模板。把它考虑为一种范型的构造函数。当要产生的确切类型很难或者是完全不可能表达而generator的结构可以直接传递给一个函数而不是存储于一个变量中的时候,一个object generator可能比一个普通的构造函数更有用。大部分boos的object generators被以make_前缀命名,就如std::make_pairt(const T&, const U&)。

For example, given:

例如,给出:

struct widget {

void tweak(int);

};

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(int 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(int arg)

{

for_each(struct_ptrs.begin(), struct_ptrs.end(),

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

std::mem_fun1_t<void, widget, int>(&widget::tweak), arg));

}

As expressions get more complicated the need to reduce the verbosity of

type specification gets more compelling.

当表达式变得更加复杂,减轻类型说明的冗长的要求变得更加迫切。

Policy Classes

A policy class 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 classes have been explored in detail by Andrei Alexandrescu in this paper. He writes:

policy类在Andrei Alexandrescu的这篇文章中被深度探究。他写道:

Policy classes are implementations of punctual design choices. They

are inherited from, or contained within, other classes. They provide

different strategies under the same syntactic interface. A class 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 classes comes from their ability to combine

freely. By combining several policy classes in a template class with

multiple parameters, one achieves combinatorial behaviors with a linear

amount of code.

policy类的威力来自于他们自由组合的能力。通过在一个模板类中用多个参数组合好几个policy类,实现了在线性数量的代码中提供组合的行为。

Andrei's description of policy classes 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

class. There is precedent for this, however: std::char_traits,

despite its name, acts as a policies class that determines the behaviors of

std::basic_string.

Andrei对于policy类的描述说明他们的威力来自于他们的颗粒性和正交性。Boost可能已经冲淡了在Iterator Adaptor库中的区别,我们在一个policy类中传播所有adapted iterator的行为。然而这有一个先例:std::char_traits,不管它的名字,就像一个policy class一样行为决定std::basic_string的行为。

Notes

[1] Type generators are a workaround for the lack of

``templated typedefs'' in C++.

type generators是为了弥补C++中缺乏"参数化的typedef"的缺陷而做的补充。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有