C++如何写adaptable仿函数

关于仿函数很多博客上都有,形式很简单,用途也很多。
一句话总结:重载了()运算符的类可以称之为仿函数functor
现在写一个“比较”

class MyLess{
public:
    bool operator()(int a, int b){
        return a < b;
    }
}; 

大多数人会这样写,其实这样写没有错,而且基本所有算法都可以通过
比如:

class MyLess{
public:
    bool operator()(int a, int b){
        return a < b;
    }
};
class Less10{
public:
    bool operator()(int a){
        return a < 10 ? true : false;
    }   
};
int main() {
    vector<int> v{1, 40, 5, 60, 5, 6};
    cout<<count_if(v.begin(), v.end(), Less10())<<endl;
    sort(v.begin(), v.end(), MyLess());
    for(auto i : v)
        cout<<i<<" ";
    cout<<endl;
}

上面两个仿函数MyLess、Less10。两个算法count_if、sort。
这样的仿函数基本上可以用stl中所有的算法。
看看STL中less怎么写的吧

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

除了模板,还有就是less继承了个binary_function,这个是什么鬼?
为什么要继承它?继承它有啥用?
看一个例子:

class MyLess{
public:
    bool operator()(int a, int b){
        return a < b;
    }
};
int main() {
    vector<int> v{1, 40, 5, 60, 5, 6};
    cout<<count_if(v.begin(), v.end(), bind2nd(less<int>(), 50))<<endl;
}

bind2nd这个叫绑定器,可以绑定一个仿函数的第二个参数。
为啥要使用绑定器?看看第段代码,有没有发现我统计数组中小于10的元素个数太单一了?一点都没有可扩展性,当我们要小于50的时候又得再写一个仿函数,太累了。所以绑定器产生了,现在C++11的绑定都是用bind这个函数(这个函数太厉害了,比bind1nd,bind2nd强大的多,有机会可以去了解下)
回到正题,如果我们把less()换成我们自己写的仿函数,编译就有问题,为啥呢?抛开模板,就是没有继承那个什么鬼了。
看看那个鬼张啥样吧

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

啥?一个成员都木有啊。
其实看STL最大的收获是懂得了typedef的使用,别看简单的一个typedef,几乎在stl中无处不在,绑定器,适配器,萃取器等等,都和typedef密不可分,但是我们正真写程序用typedef的又有几个。
回到正题,我们在看看bind2nd

template <class Operation, class T>
inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
  typedef typename Operation::second_argument_type arg2_type;
  return binder2nd<Operation>(op, arg2_type(x));
}

原来bind2nd要用typedef得到第二参数的类型啊,有啥用?为了检查第二参数是否类型正确,如果转换不了那就直接出错
so,结果就出来了,为啥要继承那个鬼。
再继续看看binder2nd吧

template <class Operation> 
class binder2nd
  : public unary_function<typename Operation::first_argument_type,
              typename Operation::result_type> {
protected:
    Operation op;
    typename Operation::second_argument_type value;
public:
    binder2nd(const Operation& x,
              const typename Operation::second_argument_type& y) 
    : op(x), value(y) {}
    result_type operator()(const argument_type& x) const {
    return op(x, value); 
    }
};

这里也需要知道参数类型和返回类型,而且binder2nd本身也是一个仿函数,而且继承了unary_function类

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

到此为止我们可以总结了

仿函数如果要融入STL那么需要继承一个类
一个参数用unary_function
两个参数用binary_function

注意:为啥binary_function有两个参数还是继承unary_function呢?
因为binary_function需要别人推导的只有第一参数而已,第二参数类型已经确定,在本类中已经typedef了

AdaptableJobFactory是Quartz中的一个接口,用于动态创建Job实例。在Quartz中,Job的实例是由Scheduler自行实例化并管理的。但是,有时候我们需要在Job运行时动态地创建Job实例,这时候就需要使用AdaptableJobFactory。 AdaptableJobFactory接口中有一个createJobInstance方法,用于创建Job实例。Quartz默认提供了一个SimpleJobFactory,用于创建Job实例。但是SimpleJobFactory只能创建无参构造函数的Job实例,如果我们需要创建有参构造函数的Job实例,则需要自定义AdaptableJobFactory。 以下是一个AdaptableJobFactory的示例代码: ```java public class MyJobFactory implements AdaptableJobFactory { private final AutowireCapableBeanFactory beanFactory; public MyJobFactory(AutowireCapableBeanFactory beanFactory) { this.beanFactory = beanFactory; } @Override public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException { JobDetail jobDetail = bundle.getJobDetail(); Class<? extends Job> jobClass = jobDetail.getJobClass(); try { Job job = beanFactory.createBean(jobClass); beanFactory.autowireBean(job); return job; } catch (Exception e) { throw new SchedulerException("Failed to create job instance", e); } } @Override public Object adapt(Objet obj) throws SchedulerException { if (obj instanceof Job) { return obj; } else if (obj instanceof JobDetail) { JobDetail jobDetail = (JobDetail) obj; Class<? extends Job> jobClass = jobDetail.getJobClass(); try { Job job = beanFactory.createBean(jobClass); beanFactory.autowireBean(job); return job; } catch (Exception e) { throw new SchedulerException("Failed to create job instance", e); } } else { throw new SchedulerException("Unsupported adaptable object"); } } } ``` 在上述代码中,我们自定义了一个MyJobFactory类,实现了AdaptableJobFactory接口。在newJob方法中,我们根据JobDetail中的Job类型创建Job实例,并对实例进行自动注入。在adapt方法中,我们判断传入的对象类型,并根据Job类型创建Job实例并自动注入。 使用自定义的AdaptableJobFactory可以参考以下代码: ```java @Bean public SchedulerFactoryBean schedulerFactoryBean(AutowireCapableBeanFactory beanFactory) { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setJobFactory(new MyJobFactory(beanFactory)); return factory; } ``` 在上述代码中,我们将自定义的MyJobFactory实例设置为Scheduler的JobFactory。这样,在Scheduler创建Job实例时,就会使用我们自定义的AdaptableJobFactory。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值