分享
 
 
 

STL中的Concept和Boost库的Concept_Check

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

在Generic Programming当中,一个重要的概念就是Concept(滑稽的是,如果把这个Concept也翻译成“概念”,那就狗屁不通了。我倾向于说它是“操作集”)。Concept就是一组操作,如果一个type具有这些操作,那么就说这个type是这个Concept的一个model。

这其中的思想有那么一丁点像是OO当中的interface,一个class如果实现了一个interface,那么它就可以被当作这个interface来用。同样,如果一个type是一个Concept的model,那么所有接受这个Concept的操作也就可以接受这个type。

例如,在STL中,stable_sort这个算法必须接受RandomAccessIterator,这里RandomAccessIterator就是一个Concept,它规定自己的model必须可以进行下标运算,那么不满足这个Concept的type就无法被编译器接受(搞笑的是我在VC71里面把list<int> 的iterator传给stable_sort,它居然欣然接受,要知道list的iterator应该只是一个BidirectionalIterator 啊,比RandomAccessIterator弱多了。不过仔细看看代码,发现VC71的stable_sort接受BidirectionalIterator就够了,不知道是好还是坏)。在gcc下面如果传递一个BidirectionalIterator给stable_sort,会得到一堆不知所云的错误提示,让人摸不着头脑。

C++语言本身并没有对于Concept的直接支持,STL解决这个问题的办法是用了一些traits来限制iterator的特性,以达到在编译时期检查Concept的目的。但是traits导致的编译错误提示实在是太可怕了,我非常怀疑有哪个正常人可以从这些错误提示推测出自己错在哪里。

在boost库里面,提供了一个ConceptCheck库,它可以帮助我们写出带有Concept检查的代码,而且没有运行时的开销,一旦用户违反Concept限制,输出的错误提示也比较好懂。举个例子先,如果STL里面有ConceptCheck,那么它的stable_sort大约会这样:

#include <boost/concept_check.hpp>

template <class RandomAccessIter>

void stable_sort(RandomAccessIter first, RandomAccessIter last)

{

function_requires< RandomAccessIteratorConcept<RandomAccessIter> >();

//... bla bla bla......

}

有了这个 function_requires ,如果再传递给它list的iterator,编译器(VC71)就会报这样的错:

c:\boost_1_31_0\boost\concept_check.hpp(642): error C2676: 二进制“+=” : “std::list<_Ty>::iterator”不定义该运算符或到预定义运算符可接收的类型的转换

with

[

_Ty=int

]

当然还有很多别的,但是至少它说了一点:传入的iterator不满足某个运算。这对于用户来说,应当是一个很有用的提示。

使用Concept Check还有一个额外的好处,那就是调用一个 function_requires可远比写一些traits容易,而且代码也清晰好维护。

这个好用的 function_requires 就定义在concept_check.hpp当中:

template <class Concept>

inline void function_requires(mpl::identity<Concept>* = 0)

{

#if !defined(NDEBUG)

void (Concept::*x)() = BOOST_FPTR Concept::constraints;

ignore_unused_variable_warning(x);

#endif

}

换句话说,function_requires只在Debug中起作用,那么是不是在Debug当中它就添加了overhead呢?其实也没有,仔细看看代码:

void (Concept::*x)() = BOOST_FPTR Concept::constraints;

这一句取constraints的地址。妙就妙在它让编译器“注意到”constraints,但又没有真正调用constraints,而constraints是一个虚函数,做实际的check。例如在RandomAccessIteratorConcept(检查iterator是否符合RandomAccessIterator的Concept)当中,constraint是这个样子:

template <class TT>

struct RandomAccessIteratorConcept

{

void constraints() {

function_requires< BidirectionalIteratorConcept<TT> >();

function_requires< ComparableConcept<TT> >();

#ifndef BOOST_NO_STD_ITERATOR_TRAITS

typedef typename std::iterator_traits<TT>::iterator_category C;

function_requires< ConvertibleConcept< C,

std::random_access_iterator_tag> >();

typedef typename std::iterator_traits<TT>::reference R;

#endif

i += n; // require assignment addition operator

i = i + n; i = n + i; // require addition with difference type

i -= n; // require assignment subtraction operator

i = i - n; // require subtraction with difference type

n = i - j; // require difference operator

(void)i[n]; // require element access operator

}

TT a, b;

TT i, j;

#ifndef BOOST_NO_STD_ITERATOR_TRAITS

typename std::iterator_traits<TT>::difference_type n;

#else

std::ptrdiff_t n;

#endif

};

从这个实现中我们完全可以读出RandomAccessIterator的具体含义:

1. 它必须是一个BidirectionalIterator

2. 它必须满足“可比较 (Comparable)”的Concept

3. 它还必须满足“可转换 (Convertible)”的Concept,而且是转换成自己的iterator_category类别

4. 它必须定义了reference这个type

5. 这是最重要的,它必须有difference_type,而且可以进行 +, -, +=, -= 的运算

还要记得,由于这个函数没有真正的被调用过,所以无论你怎么写,它都不会变成实际的代码,所以也不会影响运行效率的!

boost库除了提供了一系列的Concept Check以外,也鼓励我们自己写Concept Check,至于写法,从这个RandomAccessIteratorConcept的写法,大家也可以看出些端倪了:很简单的。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有