October 22th Tuesday

来源:互联网 发布:mac airplay怎么打开 编辑:程序博客网 时间:2024/05/29 15:46

  In the last night I have learnt how to make a generic function object with one argument.  Today I wrote an example following.

 

// fn.cpp

 

#include <boost/bind.hpp>
#include <iostream>

 

// base class

template <typename R, typename Arg> class invoker_base {
public:
  virtual R operator()(Arg arg)=0;
};

 

// the class to invoke a function by function pointer.

template <typename R, typename Arg> class function_ptr_invoker
  : public invoker_base<R, Arg> {
  R (*func_)(Arg);
public:
  function_ptr_invoker(R (*func)(Arg)):func_(func) {}
  R operator() (Arg arg) {
    return (func_)(arg);
  }
};

 

// the class to invoke a member function in an object.

template <typename R, typename Arg, typename T>
class member_ptr_invoker :
  public invoker_base<R, Arg> {
  R (T::*func_)(Arg);
  T* t_;
public:
  member_ptr_invoker(R (T::*func)(Arg), T* t)
    :func_(func), t_(t) {}

  R operator() (Arg arg) {
    return (t_->*func_)(arg);
  }
};

 

// the class to call a function object just with one argument

template <typename R, typename Arg, typename T>
class function_object_invoker :
  public invoker_base<R, Arg> {
  T t_;
public:
  function_object_invoker(T t):t_(t) {}
  R operator() (Arg arg) {
    return t_(arg);
  }
};

 

// the class of a function with one argument.

template <typename R, typename Arg> class function1 {
  invoker_base<R, Arg>* invoker_;
public:
  function1(R (*func)(Arg)) :
    invoker_(new function_ptr_invoker<R, Arg>(func)) {}

  template <typename T> function1(R (T::*func)(Arg), T* p) :
    invoker_(new member_ptr_invoker<R, Arg, T>(func, p)) {}

  template <typename T> function1(T t) :
    invoker_(new function_object_invoker<R, Arg, T>(t)) {}

  R operator() (Arg arg) {
    return (*invoker_)(arg);
  }

  ~function1() {
    delete invoker_;
  }
};

 

// example

bool some_function(const std::string s) {
  std::cout<<s<<"This is really neat/n";
  return true;
}

 

class some_class {
public:
  bool some_function(const std::string& s) {
    std::cout<<s<<"This is also quite nice/n";
    return true;
  }
};

 

class some_function_object {
public:
  bool operator() (const std::string& s) {
    std::cout<<s<<"This should work, too, in a flexible solution/n";
    return true;
  }
};

 

// main

int main() {
  function1<bool, const std::string> f1(&some_function);
  f1(std::string("Hello"));
  some_class s;
  function1<bool, const std::string&>
    f2(&some_class::some_function, &s);

  f2(std::string("Hello"));
  function1<bool, const std::string&>
    f3(boost::bind(&some_class::some_function, &s, _1));

  f3(std::string("Hello"));
  some_function_object fso;
  function1<bool, const std::string&>
    f4(fso);
  f4(std::string("Hello"));

  return 0;
}