c++ - simplified/alternative version of std::bind()/ tr1::bind() -


i using c++03. don't have std::bind(). compiler ported g++, tr1::bind() not ported.

i want bind function having 3 arguments. std::bind1st() , std::bind2nd() won't work. in addition, neither std::bind1st() or std::bind2nd() deal reference type of argument.

thus writing own version of bind1st() follows, including sample invocation of bind1st():

#include <iostream>  // c++03 not define nullptr #ifndef nullptr #define nullptr ((void*)0) #endif  namespace mybinder {  void *binder3argtobind; void *binder3functortocall;  template <int uniqueid, typename user_func_type, typename bound_func_type,           typename returntype, typename t1, typename t2, typename t3> class binder3  // 3 arguments binder { public:     static void setparams(void **parg1, void **pfunc) {             *parg1 = binder3argtobind;             *pfunc = binder3functortocall;             binder3argtobind = nullptr;     }      static returntype f_bound1st_common(t2 &arg2, t3 &arg3) {         static void *arg1;         static void *func;         returntype ignored;          if (binder3argtobind != nullptr) {             setparams(&arg1, &func);             return ignored;         }          return ((user_func_type)func)(*(t1*)arg1, arg2, arg3);     }      static returntype f_bound1st(t2 arg2, t3 arg3) {         return f_bound1st_common(arg2, arg3);     }     static returntype f_bound1st(t2 &arg2, t3 arg3) {         return f_bound1st_common(arg2, arg3);     }     static returntype f_bound1st(t2 arg2, t3 &arg3) {         return f_bound1st_common(arg2, arg3);     }     static returntype f_bound1st(t2 &arg2, t3 &arg3) {         return f_bound1st_common(arg2, arg3);     }      static bound_func_type bind1st(user_func_type f, t1 &arg1) {         binder3functortocall = (void*)f;         binder3argtobind = (void*) &arg1;          (*(void (*)())f_bound1st_common)();         return f_bound1st;     } };  }  using namespace std; using namespace mybinder;  typedef short (*func)(int const, int&);  // test function short f(int &a, int const b, int &c) {     int val = 100 * + 10 * b + c;     a+=100;     c+=10;     return val; }  int main(void) {     int a[2] = {2, 5};      (int i=0; i<2; ++i) {         // bind function f a[i] 1st argument.         func ff = binder3<__counter__, short(*)(int&, int const, int&), short(*)(int const,int&), short, int, int const, int>::bind1st(f, a[i]);          int k;         int m;         (m=0; m<2; ++m) {             k = 1-m;             cout << "before: a[i]=" << a[i] << endl;             cout << "before: m=" << m << endl;             cout << "before: k=" << k << endl;             cout << ff(m, k) << endl;             cout << "after: a[i]=" << a[i] << endl;             cout << "after: m=" << m << endl;             cout << "after: k=" << k << endl << endl;         }     } } 

and execution results:

before: a[i]=2 before: m=0 before: k=1 201 after: a[i]=102 after: m=0 after: k=11  before: a[i]=102 before: m=1 before: k=0 10210 after: a[i]=202 after: m=1 after: k=10  before: a[i]=5 before: m=0 before: k=1 501 after: a[i]=105 after: m=0 after: k=11  before: a[i]=105 before: m=1 before: k=0 10510 after: a[i]=205 after: m=1 after: k=10 

it works fine on pc, emulation. however, raises several problems in embedded compiler:

(1) embedded compiler not support __counter__

(2) invoke of bind1st() tedious, , redundant types in template may problem, if not synchronized.

thus question:

(1) how implement __counter__ in regular g++/gcc? or, in fact, need unique number/identifier counter.

(2) there anyway can derive argument types , return types function pointer type?

(3) if question (2) can done, can derive bare types reference type? example, can derive int int &? please note source type can int or int &, , need derive resulting type int in both cases. please note it's c++03, not c++11 or higher.

(4) other suggestions? perhaps can provide simpler or better implementation?

the goal of q.2 , q.3 make template call shorter, func ff = binder3<__counter__, short(*)(int&, int const, int&)>::bind1st(f, a[i]);. other types can derived first function pointer type. in addition, don't have write 4 overloads.

---update---

since implementation uses pointers binding argument , function, may have potential bug/design flaw:

if caller changes value of binding variable after calls binder3<...>::bind1st(), before use(call) of bound function, effective value value after change, not before change! can live it, careful coding. , use(call) bound function right after bind1st() (without command in-between).

ideas improve problem welcome.

--update--

currently, use of __count__ contains bug: since __count__ not globally unique (restart count 0 each compilation of .cpp file), bounding variable may overwritten, if not used promptly. if can program-wide global unique number replace __count__, above implementation should enough (except tedious stuff).


Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -