c++ - Creating and using func pointer to method of friend class -


i have 2 classes:

enum class enumtype {     typ1,     typ2, };  class { private:     rettype func1(arg1type, arg2type, arg3type);     rettype func2(arg1type, arg2type, arg3type); public:     a();     rettype func(enumtype, arg1type, arg2type, arg3type); }  class b { private:     arg1type a;     arg2type b;     arg3type c; public:     int functionfromb(enumtype); } 

so primary use this:

int b::functionfromb(enumtype x) {     a* objecta;     for(int i=0; i<whatever; i++)     {         objecta->func(x, a+i, b+(2*i), c+(3*i));     } } rettype a::func(enumtype x, arg1type a, arg2type b, arg3type c) {     switch(x)     {     case enumtype::typ1:         return func1(a, b, c);     case enumtype::typ2:         return func2(a, b, c);     default:         return func1(a, b, c);     } } 

unfortunately not want run switch every loop , thought this:

  • in class write "friend class b"
  • remove a::func()
  • make function ptr in b::functionfromb()
  • make switch in b::functionfromb(), initializes mentioned function ptr either a::func1 or a::func2. switch resemble 1 in a::func()
  • instead of running objecta->func(x, a, b, c), run objecta->functionptr(a, b, c)

how this? tried std::function, don't know how declare/initialize/call make work.

edit:
i've edited functionfromb, because i've skipped 1 important part -> func called in loop different args.

edit2:
given , have answer saying how c-style function ptr, yet want make work std::function. made (note class b , enum same):

class { private:     rettype func1(arg1type, arg2type, arg3type);     rettype func2(arg1type, arg2type, arg3type); public:     a();     typedef std::function<rettype(arg1type, arg2type, arg3type)> funcptr; }  int b::functionfromb(enumtype typeb) {     a* objecta;     a::funcptr func = nullptr;      switch(type)     {     case enumtype::typ2:         func = std::bind(&a::func2, objecta, std::placeholders::_1,                             std::placeholders::_2, std::placeholders::_3);         break;     case enumtype::typ2:     default:         func = std::bind(&a::func1, objecta, std::placeholders::_1,                             std::placeholders::_2, std::placeholders::_3);         break;     }      for(int i=0; i<whatever; i++)         func(a+i, b+(2*i), c+(3*i)); } 

and guess, works. if finds error in here or better way, please tell me ;)

could use unscoped enum enumtype?

enum enumtype {     enumtyp1,     enumtyp2,     enumtypmax }; 

if option, compiler offers free conversion int : enumtyp1 -> 0, enumtyp2 -> 1,enumtypmax -> 2 (per 3.9.2 § 10 the value of enumerator or object of unscoped enumeration type converted integer integral promotion)

the values guaranteed per 3.9.2 §2 the identifiers in enumerator-list declared constants, , can appear wherever constants required. enumeratordefinition = gives associated enumerator value indicated constant-expression. if first enumerator has no initializer, value of corresponding constant zero. enumerator-definition without initializer gives enumerator value obtained increasing value of previous enumerator one.

enum { a, b, c=0 }; enum { d, e, f=e+2 }; 

defines a, c, , d zero, b , e 1, , f 3.

you build static array of methods in , use direct array index should simpler switch :

enum enumtype {     enumtyp1,     enumtyp2,     enummax };  class { private:     typedef rettype (__thiscall a::*funcx)(arg1type,arg2type,arg3type);     rettype func1(arg1type, arg2type, arg3type);     rettype func2(arg1type, arg2type, arg3type);     static funcx fp[enummax]; public:     a();     rettype func(enumtype, arg1type, arg2type, arg3type); };  class b { private:     arg1type a;     arg2type b;     arg3type c; public:     int functionfromb(enumtype); };  int b::functionfromb(enumtype x) {     a* objecta;     for(int i=0; i<whatever; i++)     {         objecta->func(x, a+i, b+(2*i), c+(3*i));     }     return whatever; } rettype a::func(enumtype x, arg1type a, arg2type b, arg3type c) {     funcx f = a::fp[x];     return (this->*fp[x])(a, b, c); }  a::funcx a::fp[enummax] = { &a::func1, &a::func2 }; 

alternatively, directly pointer in b::functionfromb , directly call repeatedly :

enum enumtype {     enumtyp1,     enumtyp2,     enummax };  class { public:     typedef rettype (__thiscall a::*funcx)(arg1type,arg2type,arg3type); private:     rettype func1(arg1type, arg2type, arg3type);     rettype func2(arg1type, arg2type, arg3type);     static funcx fp[enummax]; public:     a();      friend class b; };  class b { private:     arg1type a;     arg2type b;     arg3type c;     a::funcx getfunc(enumtype); public:     int functionfromb(enumtype); };  a::funcx b::getfunc(enumtype x){     return a::fp[x]; }  int b::functionfromb(enumtype x) {     a* objecta;     a::funcx funcptr = getfunc(x);     for(int i=0; i<whatever; i++)     {         (objecta->*funcptr)(a+i, b+(2*i), c+(3*i));     }     return whatever; }  a::funcx a::fp[enummax] = { &a::func1, &a::func2 }; 

in latter case, avoid declaring array of methods in a, stick scoped enum enumtype , use switch once per call b::functionfromb :

a::funcx b::getfunc(enumtype x){     switch (x) {         case enumtype::typ1:             return &a::func1;         case enumtype::typ2:             return &a::func2;         case default:             return &a::func1;     } } 

Comments

Popular posts from this blog

javascript - Karma not able to start PhantomJS on Windows - Error: spawn UNKNOWN -

c# - Display ASPX Popup control in RowDeleteing Event (ASPX Gridview) -

Nuget pack csproj using nuspec -