zoukankan      html  css  js  c++  java
  • Effective STL 学习笔记 39 ~ 41

    Effective STL 学习笔记 39 ~ 41

    1 Make Predicate pure Function

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

    1. Predicate Functions should be pure function.
    2. 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。

  • 相关阅读:
    简爱 灵魂所在
    charles抓取http/https
    Class.forName()用法
    ArrayList源码剖析
    java中的多线程
    分布式负载均衡缓冲系统,如何快速定位到是那个服务器
    maven依赖jar包时版本冲突的解决
    简单工厂模式设计(java反射机制改进)
    Fiddler 抓包工具使用详解
    Fiddler 使用
  • 原文地址:https://www.cnblogs.com/yangyingchao/p/3435328.html
Copyright © 2011-2022 走看看