您的位置:首页 > Web前端

Effective STL 学习笔记 39 ~ 41

2013-11-21 12:45 295 查看


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Effective STL 学习笔记 39 ~ 41



div.org-src-container {
font-size: 85%;
font-family: monospace;
}
pre.src {
background-color:#2e3436;
color:#fefffe;
}

p {font-size: 15px}
li {font-size: 15px}

/*
@licstart The following is the entire license notice for the
JavaScript code in this tag.

Copyright (C) 2012 Free Software Foundation, Inc.

The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.

As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.

@licend The above is the entire license notice
for the JavaScript code in this tag.
*/


Table of Contents

Make Predicate pure Function

Make Functor classes adaptable

ptr_fun, mem_fun and mem_fun_ref

1 Make Predicate pure Function

纯函数 (Pure Function) 是指输出仅在输入变化时才发生变化的的函数,换句话说,该类型函数的输出不依赖于输入之外的任何东西,例如自身状态或者全局变量。这也是 Functional Programming 中的一个重要概念。 C++ 中用于 STL 算法的
Functor 是一些 Predicate Class ,这些 Class 的 operator() 是预测函数,这些 Predicate Class
的 operator() 也应该是纯函数,且不能修改 Class 内部成员变量 —— 换句话说,典型的 Const Member
Function。

Predicate Functions should be pure function.

Predicate Class should make operator() const member function.

2 Make Functor classes adaptable

~~(╯﹏╰)b, 各种从 unary/binary_function 继承过来的东东。。。。见下面的代码。。。

3 ptr_fun, mem_fun and mem_fun_ref

这几个函数用于生成前面提到的 unary/binary_function:

// 20.3.7 adaptors pointers functions
/** @defgroup pointer_adaptors Adaptors for pointers to functions
* @ingroup functors
*
*  The advantage of function objects over pointers to functions is that
*  the objects in the standard library declare nested typedefs describing
*  their argument and result types with uniform names (e.g., @c result_type
*  from the base classes @c unary_function and @c binary_function).
*  Sometimes those typedefs are required, not just optional.
*
*  Adaptors are provided to turn pointers to unary (single-argument) and
*  binary (double-argument) functions into function objects.  The
*  long-winded functor @c pointer_to_unary_function is constructed with a
*  function pointer @c f, and its @c operator() called with argument @c x
*  returns @c f(x).  The functor @c pointer_to_binary_function does the same
*  thing, but with a double-argument @c f and @c operator().
*
*  The function @c ptr_fun takes a pointer-to-function @c f and constructs
*  an instance of the appropriate functor.
*
*  @{
*/
/// One of the @link pointer_adaptors adaptors for function pointers@endlink.
template<typename _Arg, typename _Result>
class pointer_to_unary_function : public unary_function<_Arg, _Result>
{
protected:
_Result (*_M_ptr)(_Arg);

public:
pointer_to_unary_function() { }

explicit
pointer_to_unary_function(_Result (*__x)(_Arg))
: _M_ptr(__x) { }

_Result
operator()(_Arg __x) const
{ return _M_ptr(__x); }
};

/// One of the @link pointer_adaptors adaptors for function pointers@endlink.
template<typename _Arg1, typename _Arg2, typename _Result>
class pointer_to_binary_function
: public binary_function<_Arg1, _Arg2, _Result>
{
protected:
_Result (*_M_ptr)(_Arg1, _Arg2);

public:
pointer_to_binary_function() { }

explicit
pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2))
: _M_ptr(__x) { }

_Result
operator()(_Arg1 __x, _Arg2 __y) const
{ return _M_ptr(__x, __y); }
};

/// One of the @link pointer_adaptors adaptors for function pointers@endlink.
template<typename _Arg, typename _Result>
inline pointer_to_unary_function<_Arg, _Result>
ptr_fun(_Result (*__x)(_Arg))
{ return pointer_to_unary_function<_Arg, _Result>(__x); }

/// One of the @link pointer_adaptors adaptors for function pointers@endlink.
template<typename _Arg1, typename _Arg2, typename _Result>
inline pointer_to_binary_function<_Arg1, _Arg2, _Result>
ptr_fun(_Result (*__x)(_Arg1, _Arg2))
{ return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); }

/**
*  This is one of the @link functors functor base classes@endlink.
*/
template<typename _Arg, typename _Result>
struct unary_function
{
/// @c argument_type is the type of the argument
typedef _Arg    argument_type;

/// @c result_type is the return type
typedef _Result     result_type;
};

/**
*  This is one of the @link functors functor base classes@endlink.
*/
template<typename _Arg1, typename _Arg2, typename _Result>
struct binary_function
{
/// @c first_argument_type is the type of the first argument
typedef _Arg1   first_argument_type;

/// @c second_argument_type is the type of the second argument
typedef _Arg2   second_argument_type;

/// @c result_type is the return type
typedef _Result     result_type;
};

// 20.3.8 adaptors pointers members
/** @defgroup memory_adaptors Adaptors for pointers to members
* @ingroup functors
*
*  There are a total of 8 = 2^3 function objects in this family.
*   (1) Member functions taking no arguments vs member functions taking
*        one argument.
*   (2) Call through pointer vs call through reference.
*   (3) Const vs non-const member function.
*
*  All of this complexity is in the function objects themselves.  You can
*   ignore it by using the helper function mem_fun and mem_fun_ref,
*   which create whichever type of adaptor is appropriate.
*
*  @{
*/
/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp>
class mem_fun_t : public unary_function<_Tp*, _Ret>
{
public:
explicit
mem_fun_t(_Ret (_Tp::*__pf)())
: _M_f(__pf) { }

_Ret
operator()(_Tp* __p) const
{ return (__p->*_M_f)(); }

private:
_Ret (_Tp::*_M_f)();
};

/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp>
class mem_fun_ref_t : public unary_function<_Tp, _Ret>
{
public:
explicit
mem_fun_ref_t(_Ret (_Tp::*__pf)())
: _M_f(__pf) { }

_Ret
operator()(_Tp& __r) const
{ return (__r.*_M_f)(); }

private:
_Ret (_Tp::*_M_f)();
};

// Mem_fun adaptor helper functions.  There are only two:
// mem_fun and mem_fun_ref.
template<typename _Ret, typename _Tp>
inline mem_fun_t<_Ret, _Tp>
mem_fun(_Ret (_Tp::*__f)())
{ return mem_fun_t<_Ret, _Tp>(__f); }

template<typename _Ret, typename _Tp>
inline mem_fun_ref_t<_Ret, _Tp>
mem_fun_ref(_Ret (_Tp::*__f)())
{ return mem_fun_ref_t<_Ret, _Tp>(__f); }


简单来说:

ptr_fun 用于将函数指针转换成 unay_function 或者 binary_function

mem_fun 用于将成员函数指针转换成 unay_function 或者 binary_function

mem_fun_ref

同 mem_fun ,不同之处在于 mem_fun 返回的 Functor 接受的是对象指针,而 mem_fun_ref 返回的
Functor 接受的参数为对象引用。

在使用 STL 时候,尽量使用上述的三个函数来生成 functor。

(转载请注明出处,使用许可:署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: