boost函数对象的妙用
2011-08-08 09:32
204 查看
今天在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]
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]
相关文章推荐
- 【C++】boost::bind和函数对象一起使用实现便捷的异步编程
- boost 函数对象和高阶编程概述
- Boost关于bind的使用以及函数对象和传递参数的问题
- Boost 函数对象
- C++ boost 组件简介:函数对象及高级编程
- Boost.Bind用法详解(一) 2008-05-09 15:50:50| 分类: C++ |字号 订阅 Boost.Bind 为函数和函数对象提供了一致的语法,对于值语义和指针语义也一样。
- boost::thread 使用函数对象来构造线程对象的问题
- Boost函数对象 boost.bind boost.function Boost.Ref Boost.Lambda
- boost::bind绑定成员函数时,第一个参数传递对象的特殊情况
- boost python 函数中传递对象
- Boost Part III. 函数对象与高级编程 Library 10. Lambda 用法
- Boost学习------函数对象
- Boost学习系列3-函数对象(上)
- [boost-3] 函数对象
- 共享boost::deadline_timer封装模板,可以接受任何函数对象
- 函数对象function object 以及boost::bind的一点了解
- Boost学习系列3-函数对象(下)
- Boost Part III. 函数对象与高级编程 Library 10. Lambda 用法 switch_statement
- 你注意到C++的函数对象都是传值的形式了吗?---boost::ref的强大用处~
- Boost库中的函数对象