码迷,mamicode.com
首页 > 其他好文 > 详细

从零开始写STL—functional

时间:2018-03-29 17:27:21      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:first   绑定   opera   str   typedef   符号   ++   binder   获取   

function C++11 将任意类型的可调用(Callable)对象与函数调用的特征封装到一起。
这里的类是对函数策略的封装,将函数的性质抽象成组件,便于和algorithm库配合使用

基本运算符 和 基本比较符号组件

    template<class Arg, class Result>
    struct unary_function
    {
        typedef Arg argument_type;
        typedef Result result_type;
    };

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

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

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

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

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

    template<class T>
    struct negate :unary_function<T, T>
    {
        T operator()(const T& x) const
        {
            return -x;
        }
    };

    template<class T>
    struct less :binary_function<T, T, bool>
    {
        bool operator()(const T&lhs, const T& rhs) const
        {
            return lhs < rhs;
        }
    };
    
    template <class T>
    struct greater : binary_function<T, T, bool>
    {
        bool operator()(const T& lhs, const T& rhs) const
        {
            return lhs > rhs;
        }
    };

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

    template<class T>
    struct greater_equal : binary_function<T, T, bool>
    {
        bool operator()(const T& lhs, const T& rhs)
        {
            return lhs >= rhs;
        }
    };

    template<class T>
    struct less_equal : binary_function<T, T, bool>
    {
        bool operator()(const T& lhs, const T& rhs)
        {
            return lhs <= rhs;
        }
    };

逻辑运算组件

对已经封装好的函数组件的运行结果增加一层封装。

    template <class Predicate>
    class unary_negate
        : public unary_function <typename Predicate::argument_type, bool>//参数类型是传入Predicate的参数类型,返回类型为bool
    {
    protected:
        Predicate fn;
    public:
        explicit unary_negate(const Predicate& pred) : fn(pred) {}
        bool operator() (const typename Predicate::argument_type& x) const
        {
            return !fn(x);
        }
    };

    template <class Predicate>
    class binary_negate
        : public binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>
    {
    protected:
        Predicate fn;
    public:
        explicit binary_negate(const Predicate& pred) :fn(pred) {}
        bool operator() (const typename Predicate::first_argument_type& x,
            const typename Predicate::second_argument_type& y) const
        {
            return !fn(x, y);
        }
    };

参数绑定

将要调用的参数保存在结构中,调用的时候再传入
使用typename 和 模板 来指明返回类型 和 参数类型
建议使用explicit来避免隐式类型转换

    template<class Operation>
    class binder1st
        : public binary_function<typename Operation::first_argument_type, typename Operation::second_argument_type, typename  Operation::result_type>
    {
    protected:
        typename Operation::first_argument_type val;//要绑定的参数
        Operation op;
    public:
        explicit binder1st(const Operation& operation, const typename Operation::first_argument_type x) :op(operation),val(x) {}
        typename Operation::result_type operator()(const typename Operation::second_argument_type& xs)
        {
            return op(val, x);
        }
    };


    //绑定第二个参数
    template<class Operation>
    class binder2nd
        : public binary_function<typename Operation::first_argument_type, typename Operation::second_argument_type, typename  Operation::result_type>
    {
    protected:
        typename Operation::second_argument_type val;
        Operation op;
    public:
        explicit binder2nd(const Operation& operation, const typename Operation::second_argument_type x) :op(operation),val(x) {}
        typename Operation::result_type operator()(const typename Operation::first_argument_type& xs)
        {
            return op(x, val);
        }
    };

不定参数的绑定

底层数据 结构用tuple来实现,对于调用参数的获取,维护一个tuple inddex 模板类,去在模板中递归生成对应下标。

    //绑定不定数目 不定类型的参数
    //底层数据通过tuple来保存实现
    要实现
    template <class F, class... Args>
    struct binder
    {
        //使用std::forward 进行完美转发
        //可见 http://en.cppreference.com/w/cpp/utility/forward
        binder(F&& f, Args&&... args) :data(std::forward<F>(f), std::forward<Args>(args)...) {}
        inline auto operator()()
        {
            typedef typename make_tuple_indices<std::tuple_size<std::tuple<F, Args...> >::value, 1>::type index_type;
            return run2(index_type());
        }
        template <std::size_t... Indices>
        void run2(tuple_indices<Indices...>)
        {
            //模板展开
            invoke(std::move(std::get<0>(data)), std::move(std::get<Indices>(data))...);
        }
        inline auto invoke(F&& f, Args&&... args)
        {
            //f 作为函数指针 ,args 作为参数传入
            return std::forward<F>(f)(std::forward<Args>(args)...);
        }
        //使用tuple来保存数据
        std::tuple<F,Args...> data;
    };
    

    template <class F, class... Args >
    ministl::binder<F,Args...> bind(F&& f, Args&&... args)
    {
        return binder<F, Args...>(std::forward<F>(f), std::forward<Args>(args)...);
    }

从零开始写STL—functional

标签:first   绑定   opera   str   typedef   符号   ++   binder   获取   

原文地址:https://www.cnblogs.com/joeylee97/p/8670888.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!