boost函数对象的妙用
分享
今天在boost中看到了如下的函数用法:
trim_copy_if(str,is_punct()||is_digit()||is_space()) 作用是将字符串str两端的所有的标点,数字和空格都去掉,这种用法很奇妙,能够把函数或起来,仔细看了一下后台的实现代码,实现的很奇妙,值得记录一下,
1. is_punct(),is_digit()和is_space() 三个从表面上看是函数,但是实际上他们返回的是structure对象,拿is_digit()查看,其后台实现代码为:
inline detail::is_classifiedF is_space(const std::locale& Loc=std::locale()) { return detail::is_classifiedF(std::ctype_base::space, Loc); }
其返回的是is_classifiedF对象,该对象实际上是一个structure()对象,其定义如下:
struct is_classifiedF : public predicate_facade<is_classifiedF> { // Boost.ResultOf support typedef bool result_type; // Constructor from a locale is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : m_Type(Type), m_Locale(Loc) {} // Operation template<typename CharT> bool operator()( CharT Ch ) const { return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch ); } #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL) template<> bool operator()( char const Ch ) const { return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch ); } #endif private: std::ctype_base::mask m_Type; std::locale m_Locale; };
第一步的实现比较容易理解,返回一个structure对象,并在该structure对象中重载了()符号。
2. 第二步是查看如何将这些函数或起来,实际上就是如何将这三个structure或起来,查看一些||操作符的实现代码,如下:
template<typename Pred1T, typename Pred2T> inline Prefor_<Pred1T, Pred2T> operator||( const base<Pred1T>& Pred1, const base<Pred2T>& Pred2 ) { // Doing the static_cast with the pointer instead of the reference // is a workaround for some compilers which have problems with // static_cast's of template references, i.e. CW8. /grafik/ return Prefor_<Pred1T,Pred2T>( *static_cast<const Pred1T*>(&Pred1), *static_cast<const Pred2T*>(&Pred2)); }
从上面的代码中可以看出,该操作将两个is_classifiedF structure或成一个 Prefor_对象,那三个函数或起来的步骤是:
先将is_punct()和is_digit()两个对象或成一个临时的Prefor_对象,接着这个临时的Prefor_对象与is_space()函数再或成一个Prefor_对象。
3. Prefor_对象也是一个structure,该对象也实现了()操作符,以下是该结构的定义
template<typename Pref1, typename Pref2> struct Prefor_:public base<Prefor_<Pref1,Pref2> > { Prefor_(Pref1 pref1, Pref2 pref2):m_pref1(pref1),m_pref2(pref2){} template<typename CharT> bool operator() (CharT c) { return m_pref1(c) || m_pref2(c); } Pref1 m_pref1; Pref2 m_pref2; };
在()符号重载中,发现其实际上调用的也是[b]is_classifiedF的()操作符。由于我们是三个函数或在一起的,因此该()操作符中是有一次递归调用的。[/b]
文章来源:http://blog.csdn.net/liufeng1980423/article/details/6668168
trim_copy_if(str,is_punct()||is_digit()||is_space()) 作用是将字符串str两端的所有的标点,数字和空格都去掉,这种用法很奇妙,能够把函数或起来,仔细看了一下后台的实现代码,实现的很奇妙,值得记录一下,
1. is_punct(),is_digit()和is_space() 三个从表面上看是函数,但是实际上他们返回的是structure对象,拿is_digit()查看,其后台实现代码为:
inline detail::is_classifiedF is_space(const std::locale& Loc=std::locale()) { return detail::is_classifiedF(std::ctype_base::space, Loc); }
其返回的是is_classifiedF对象,该对象实际上是一个structure()对象,其定义如下:
struct is_classifiedF : public predicate_facade<is_classifiedF> { // Boost.ResultOf support typedef bool result_type; // Constructor from a locale is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : m_Type(Type), m_Locale(Loc) {} // Operation template<typename CharT> bool operator()( CharT Ch ) const { return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch ); } #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL) template<> bool operator()( char const Ch ) const { return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch ); } #endif private: std::ctype_base::mask m_Type; std::locale m_Locale; };
第一步的实现比较容易理解,返回一个structure对象,并在该structure对象中重载了()符号。
2. 第二步是查看如何将这些函数或起来,实际上就是如何将这三个structure或起来,查看一些||操作符的实现代码,如下:
template<typename Pred1T, typename Pred2T> inline Prefor_<Pred1T, Pred2T> operator||( const base<Pred1T>& Pred1, const base<Pred2T>& Pred2 ) { // Doing the static_cast with the pointer instead of the reference // is a workaround for some compilers which have problems with // static_cast's of template references, i.e. CW8. /grafik/ return Prefor_<Pred1T,Pred2T>( *static_cast<const Pred1T*>(&Pred1), *static_cast<const Pred2T*>(&Pred2)); }
从上面的代码中可以看出,该操作将两个is_classifiedF structure或成一个 Prefor_对象,那三个函数或起来的步骤是:
先将is_punct()和is_digit()两个对象或成一个临时的Prefor_对象,接着这个临时的Prefor_对象与is_space()函数再或成一个Prefor_对象。
3. Prefor_对象也是一个structure,该对象也实现了()操作符,以下是该结构的定义
template<typename Pref1, typename Pref2> struct Prefor_:public base<Prefor_<Pref1,Pref2> > { Prefor_(Pref1 pref1, Pref2 pref2):m_pref1(pref1),m_pref2(pref2){} template<typename CharT> bool operator() (CharT c) { return m_pref1(c) || m_pref2(c); } Pref1 m_pref1; Pref2 m_pref2; };
在()符号重载中,发现其实际上调用的也是[b]is_classifiedF的()操作符。由于我们是三个函数或在一起的,因此该()操作符中是有一次递归调用的。[/b]
文章来源:http://blog.csdn.net/liufeng1980423/article/details/6668168
0 个评论
推荐内容
相关问题
- Arcgis10.4 创建企业级地理数据库 “用户不具有创建数据库对象的必要权限 ”
- 重复创建内存工作空间 ,系统内存上升很快,调用Marshal.ReleaseComObject释放AE对象 并没有起作用,请问如何正确的释放所有的AE对象?
- 调用arcpy.SelctLayerByAttribute函数出现问题!
- Cityengine中,在坡面上直接生成的建筑是倾斜的,请问要用什么函数使建筑保持水平。
- 在CityEngine的CGA代码中 p() 函数是什么意思?
- 怎么获取鼠标点击的graphic对象啊???
- 使用IObjectCopy进行map对象拷贝后,造成滚轮异常
- 用服务对象扩展(SOE)连接数据库oracle结果不显示
- arcgis api for javascript 怎么实现移动编辑对象?
- 如何通过ArcObjects对象调用设置工作空间窗体?
- Arcgis pro 深度学习 “无法保存标注样本对象以供运行使用”报错