作者: my_passion | 来源:发表于2022-09-24 23:54 被阅读0次

<functional>

函数对象/functor

1 Base classes

(1) unary_function<ArgType, ReturnType> 1元函数对象基类: 只 typedef 参数类型 和 返回值类型 为 argument_type 和 result_type

template <class Arg, class Result>
struct unary_function 
{
    typedef Arg     argument_type; // `参数类型`
    typedef Result  result_type;   // `返回值类型` 
};

(2) binary_function<Arg1Type, Arg2Type, ReturnType> 2元函数对象基类

template <class Arg1, class Arg2, class Result>
struct binary_function 
{
    typedef Arg1    first_argument_type;
    typedef Arg2    second_argument_type;
    typedef Result  result_type;
};

2 Operator classes

模板参数 只用1个: 操作的元素类型

(1) 算术 Arithmetic

`plus<T>`
    
    template <class T> 
    struct plus: binary_function <T, T, T> 
    {
        T operator() (const T& x, const T& y) const 
        {
            return x + y;
        }
    };

minus 

multiplies

divides

modulus %

negate  取 负

(2) 比较 Comparison

`equal_to<T>`
    |
    not_equal_to
    
    template <class T> 
    struct equal_to: binary_function <T, T, bool> 
    {
        bool operator() (const T& x, const T& y) const 
        {
            return x == y;
        }
    };

`less<T>`           // < 
    |
    `greater`       // >
    
    template <class T> 
    struct less: binary_function <T, T, bool> 
    {
        bool operator() (const T& x, const T& y) const 
        {
            return x < y;
        }
    };

`less_equal<T>`     // <=
    |
    greater_equal   // >=

(3) 逻辑

`logical_and<T>`
    |
    logical_or
    |
    logical_not
    
    template <class T> 
    struct logical_and: binary_function <T, T, bool> 
    {
        bool operator() (const T& x, const T& y) const 
        {
            return x&&y;
        }
    };

3 Adaptor and conversion functions: 适配器 和 转换函数 均为 函数模板, 返回相应含义的 函数对象, 内部保存 boolFunctorObj(boolFunctorObj) / OperationObj 和 第1(2)参数 / 函数指针, 成员函数指针

(1) 否定: Negators, 返回的 函数对象(内部保存 boolFunctorObj/Predicate) -> 对元素转调 boolFunctorObj 的返回值取否定(!)

`not1(pred)`
    
    template <class Predicate> 
        unary_negate<Predicate> 
    not1 (const Predicate& pred)
    {
        return unary_negate<Predicate>(pred);
    }
    
    template <class Predicate> 
    class unary_negate
      : public unary_function <typename Predicate::argument_type, bool>
    {
    protected:
        Predicate pred;
    public:
        explicit unary_negate (const Predicate& pred_) 
            : pred (pred_)      // [1] 存 pred
        {}
            
        bool operator() (const typename Predicate::argument_type& x) const 
        {
            return !pred(x);    // [2] 调用的返回值取否定
        }
    };

`not2` // 思路类似 not1

(2) 参数绑定: Parameter binders 返回的 函数对象(内部保存 OperationObj 和 第1参数) -> 对元素 转调 OperationObj 时只带第2参数

`bind1st(op, x)`    
    
    template <class Operation, class T>
        binder1st<Operation> 
    bind1st (const Operation& op, const T& x)
    {
        return binder1st<Operation>(op, typename Operation::first_argument_type(x));
    }

    template <class Operation> 
    class binder1st: public unary_function <typename Operation::second_argument_type,
                                            typename Operation::result_type>
    {
    protected:
        Operation op;
        typename Operation::first_argument_type arg1;
    public:
        binder1st ( const Operation& x,
                    const typename Operation::first_argument_type& arg1_) 
            : op (op_), arg1(arg1_) {}  // [1] 存 OperationObj 和 第1参数
            
        typename Operation::result_type
        operator() (const typename Operation::second_argument_type& arg2) const
        { 
            return op(arg1, arg2);      // [2] 对元素 调用 OperationObj 时只带第2参数
        }
    };

`bind2nd`

(3) 转换 Conversors

// Note: `由函数实参 可推导出 模板形参列表`

`ptr_fun(pFunc)` 

`mem_fun(pMemFunc)`

`mem_fun_ref(pMemFunc)`

——————————————————————————————————————————————————————————————————————————————————————————
            from            to 
——————————————————————————————————————————————————————————————————————————————————————————
ptr_fun     `函数指针: 带 1/2个参数`        functor

mem_fun     `成员函数指针: 带 0/1个参数`  functor (指针版)   `用类的指针 调用 成员函数指针`

mem_fun_ref 成员函数指针: 带 0/1个参数        functor (引用版)   `用类对象的引用 调用 成员函数指针`
——————————————————————————————————————————————————————————————————————————————————————————

// === 1
template <class Arg, class Result>
    pointer_to_unary_function<Arg, Result> 
ptr_fun (Result (*pf)(Arg) )
{
    return pointer_to_unary_function<Arg, Result>(pf);
}
    |
    |
    template <class Arg1, class Arg2, class Result>
        pointer_to_binary_function<Arg1, Arg2, Result> 
    ptr_fun (Result (*pf)(Arg1, Arg2) )
    {
        return pointer_to_binary_function<Arg1,Arg2,Result>(pf);
    }

    template <class Arg, class Result>
    class pointer_to_unary_function : public unary_function <Arg, Result>
    {
    protected:
        Result(*pf)(Arg);
    public:
        explicit pointer_to_unary_function ( Result (*pf_)(Arg) ) 
            : pf (pf_) {}  // [1]
        
        Result operator() (Arg x) const
        { 
            return pf(x);  // [2]
        }
    };

// === 2
// 成员函数指针不带参数
template <class ReturnType, class T> 
    mem_fun_t<ReturnType,T> 
mem_fun (ReturnType (T::*f)() )
{ 
    return mem_fun_t<ReturnType,T>(f); 
}

    // 成员函数指针带1个参数
    template <class ReturnType, class T, class ArgType> 
        mem_fun1_t<ReturnType, T, ArgType> 
    mem_fun (ReturnTypeS (T::*f)(ArgType) )
    { 
        return mem_fun1_t<ReturnType, T, ArgType>(f); 
    }

    template <class ReturnType, class T>
    class mem_fun_t : public unary_function <T*, ReturnType>
    {
        ReturnType (T::*pMemFunc)();
    public:
        explicit mem_fun_t ( ReturnType (T::*pMemFunc_)() ) 
            : pMemFunc (pMemFunc_) {}
            
        ReturnType operator() (T* pT) const // 用类的指针 调用 成员函数指针
        { 
            return (pT->*pMemFunc)(); 
        }
    };

// === 3
mem_fun_ref

    ReturnType operator() (T& p) const
    { 
        return (p.*pmem)(); 
    }

4 例

(1)
    struct IsOdd 
    {
        bool operator() (const int& x) const 
        {
            return x%2 == 1;
        }
        typedef int argument_type;
    };
    
    std::count_if (vec.begin(), vec.end(), std::not1(IsOdd() ) );

(2)
    count_if (numbers, numbers+6, bind1st(equal_to<int>(), 10) );
        
(3) 
    char* foo[] = {"10","20","30","40","50"};
    int bar[5];
    transform (foo, foo+5, bar, ptr_fun(atoi) );
    
    vector <string*> numbers;
    // ... 
    vector <int> lengths ( numbers.size() );
    transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fun(&string::length) );

    transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fun_ref(&string::length));

相关文章

网友评论

      本文标题:

      本文链接:https://www.haomeiwen.com/subject/jjezortx.html