I have a functor class with an internal state and fixed output type and fixed parameters necessary for constructing the object:
class Functor
{
public:
/* constructor */
Functor(double var1, double var2 ...)
{
/* some initialization of internal variables */
}
array<double,N> operator()(double par1, ...)
{
array<double,N> output;
/* some calculations using private member functions */
return output;
}
private:
/* internal variables */
double internal_var1;
...
/* internal functions */
double internal func1(double var1, ...)
{
/* calculation */
}
...
};
This functor is instantiated in the main program using input parameters from the user.
I want to use this functor inside the member functions of other classes, which are also functors, for further calulations. One important aspect specific to this question is, that these functors use a specific signature that i cannot alter, otherwise i would just provide these functors with the result of the initial functor (i.e. the one of class Functor) as input parameters when calling them.
My idea so far (which quickly turned out to be nonsense) was to have these classes have a member that is a pointer to a class of the aforementioned functor and provide the constructor of these classes a reference to the functor:
class C1
{
public:
/* constructor */
C1(/* some parameters */, Functor* functor) // this is probably nonsense
{
/* C1 member initialization */
...
functor_ptr = functor;
}
void operator()(/* !!! fixed parameter signature here !!! */)
{
/* calulations using internal functions... */
}
private:
/* member variables and the functor class pointer*/
double internal_var1;
... etc. ...
Functor* functor_ptr;
/* member functions */
double internal_func1(double par1, ...)
{
/* use the functor */
double<array,N> tmp = (*functor_ptr)(par1, par2, ...) // more nonsense
/* more calculations */
return result;
}
double internal_func2(...)
... etc. ...
};
From what i looked up so far it seems that using a std:function call inside C1 could achieve what i'm trying to do (and i can use c++11). This post seems very similar to what i want, however, i can't figure out how to attach my functor to the std::function call as my C(ung)-fu is still rather weak. Also i couldn't figure out if it is possible to have something like std:function<array<double,N>(double,double,...> call_functor as a member of a class , which is the initialized in the constructor.
Can, and if yes how, this be done using std::function or is there a better way?
Indeed, return a function with std:function<array<double,N>(double,double,...)>, and to create it use a lambda:
std:function<array<double,N>(double,double,...)>([this](double x, double y, ...){return this->function(x, y,);};
You need to capture this of course to know on which object the method should be called.
Related
I have my fancyFunction which takes a set of elements implementing interface A. The function does a complicated analysis of those elements, based on properties read through interface A. During this analysis, it will call methods of a Consumer c which will take the elements as arguments.
The Consumer is designed to take arguments of a specific type which has absolutely nothing to do with A.
You could imagine that A is an abstraction for edges in a graph. The graph is analyzed in fancyFunction and - for example - every time the function "crosses" an edge, it will send that edge to a Consumer which prints additional information stored in the edge that has nothing to do with it being an edge.
The code given below would of course not compile in a typed language (particularly C++), but leaving out the types (Matlab, Python), the code would work.
To make it work in a typed language (particularly C++), I see two options:
Declare the function as
template <class CONSUMER>
void fancyFunction(A[] setOfAs, CONSUMER c){ ... }
Declare operation1 and operation2 to take the most general object and then do a downcast in the implementation.
What do you recommend to do in that situation? (As far as I see, the visitor pattern is NOT an option.)
Full code outline (I did not use C++ in a while, so please excuse if there are minor syntactical mistakes.):
void fancyFunction(A[] setOfAs, Consumer* c){
// do fancy analysis of setOfAs by properties
// read through interface A
double x = setOfAs[i]->getX();
// call functions in c with arguments of setOfAs[j]
...
c->operationX(setOfAs[i]);
...
c->operationY(setOfAs[j]);
...
}
class A{
virtual double getX();
}
class Consumer{
virtual void operationX(??? x); // whoops, what type do we expect?
virtual void operationY(??? y); // whoops, what type do we expect?
}
class Consumer1{
void operationX(Obj1 x){ ... } // whoops, override with different type
void operationY(Obj1 y){ ... } // whoops, override with different type
}
class Consumer2{
void operationX(Obj2 x){ ... } // whoops, override with different type
void operationY(Obj2 y){ ... } // whoops, override with different type
}
class Obj1 : public A {};
class Obj2 : public A {};
void test(){
Obj1 o1[];
Obj2 o2[];
Callback1 c1;
Callback2 c2;
fancyFunction(o1, &c1);
fancyFunction(o2, &c2);
}
I believe the solution you're looking for is called the Visitor Pattern.
You don't want to manually cast each instance of object A in your fancy function, because that is a maintenance nightmare and a clear code smell.
On the other hand, what if each object automatically handled its own casting? That's the Visitor Pattern.
You begin by defining a new "Visit" function in your base class (A), taking your Consumer as its only argument:
class A
{
public:
virtual void Visit(Consumer& consumer) = 0;
}
You then implement this function for every inherited class, thusly:
class B : public A
{
public:
void Visit(Consumer& consumer)
{
consumer.DoOperation(this); // 'this' utomatically resolves to type B*
}
}
Each derived type now handles calling the appropriate operation overload, by passing the 'this' pointer to the provided Consumer instance. The 'this' pointer is automatically interpreted as the most specific type possible.
Looking back through your original example code, it appears you have each Consumer providing multiple operations, and only handling a single type. This pattern would likely require that you change this paradigm slightly: create a single Consumer for each operation, where each consumer provides overloads for every possible inherited type.
class ConsumerX
{
public:
void DoOperation(A* a) { /* ERROR! This is a base type. If this function is called, you probably need to implement another overload. */ }
void DoOperation(B* b) { /* Much better */ }
}
class ConsumerY
{
public:
void DoOperation(A* a) { /* ERROR! This is a base type. If this function is called, you probably need to implement another overload. */ }
void DoOperation(B* b) { /* Much better */ }
}
Then your implementation loop looks something like this:
ConsumerX consumerX; // Does Operation X for every type
ConsumerY consumerY; // Does Operation Y for every type
for(int x = 0; x < numElements, x++)
{
auto element = setOfAs[x];
element.Visit(consumerX); //Do operation X
element.Visit(consumerY); //Do operation Y
}
Clearly a case where templates are appropriate. I'd even question why your fancyFunction is insisting on base class A. It should just take a begin and end iterator. I wouldn't bother with a consumer either. Make that flexible too, just take any function.
In fact, I wouldn't even write a fancyFunction. It already exists:
std::for_each(o1.begin(), o1.end(),
[c1](Obj1 o) { double x = o.getX(); c1.operationX(o); c1.operationY(o); }
);
I have something like the following:
QuadMesh.h:
#include "StructureIpsim.h" // this is a struct
class QuadMesh {
public:
QuadMesh(StructureIpsim s) {//do stuff}
};
SEMPotential.h:
#include "QuadMesh.h"
#include "SpecialFuncs.h"
class SEMPotential {
public:
StructureIpsim SI;
QuadMesh mesh;
SEMPotential( //args);
};
SEMPotential::SEMPotential( //args) {
// init structure in here, need to call functions from SpecialFuncs.h to do so
// How to construct the QuadMesh object mesh? Can't put in initialization list.
}
As you can see, the QuadMesh object takes in a StructureIpsim sruct, but this struct must be initialized using several functions in the constructor of SEMPotential before being passed to the QuadMesh constructor. What's the standard way around this?
You CAN use the initializer-list. Use a helper function, which should probably be a private static member function, that accepts the relevant arguments, does the calculations, and returns a QuadMesh object. Use the initialization list to initialize the member from the return value of that helper.
class SEMPotential
{
static QuadMesh mesh_creator( /* args */ );
public:
QuadMesh mesh;
SEMPotential(/* args */) : mesh(mesh_creator(args)) {}
};
QuadMesh SEMPotential::mesh_creator( /*args*/ )
{
StructureIpsum s;
// init structure in here, calling functions from SpecialFuncs.h to do so
return QuadMesh(s);
}
As Matt McNabb points out in his comment, that helper function could be a constructor of StructureIpsum. But I present a solution that doesn't require modifying StructureIpsum or QuadMesh class definitions.
If you want to preserve the StructureIpsum instance, use the helper method trick to initialize it, and then simply use it to initialize the mesh:
SEMPotential(/* args */) : SI(ipsum_creator(args)), mesh(SI) {}
Initialization order of members is guaranteed (it's the order they appear in the class, the ordering in the initialization list has no effect).
I am creating a bunch of C structs so i can encapsulate data to be passed over a dll c interface. The structs have many members, and I want them to have defaults, so that they can be created with only a few members specified.
As I understand it, the structs need to remain c-style, so can't contain constructors. Whats the best way to create them? I was thinking a factory?
struct Foo {
static Foo make_default ();
};
A factory is overkill. You use it when you want to create instances of a given interface, but the runtime type of the implementation isn't statically known at the site of creation.
The C-Structs can still have member functions. Problems will, however, arise if you start using virtual functions as this necessitates a virtual table somewhere in the struct's memory. Normal member functions (such as a constructor) don't actually add any size to the struct. You can then pass the struct to the DLL with no problems.
I would use a constructor class:
struct Foo { ... };
class MakeFoo
{
Foo x;
public:
MakeFoo(<Required-Members>)
{
<Initalize Required Members in x>
<Initalize Members with default values in x>
}
MakeFoo& optionalMember1(T v)
{
x.optionalMember1 = v;
}
// .. for the rest option members;
operator Foo() const
{
return x;
}
};
This allows to arbitrary set members of the struct in expression:
processFoo(MakeFoo(1,2,3).optionalMember3(5));
I have an easy idea, here is how:
Make the structure, just like you normally would, and create a simple function that initializes it:
struct Foo{...};
void Default(Foo &obj) {
// ... do the initialization here
}
If you have multiple structures, you are allowed in C++ to overload the function, so you can have many functions called 'default', each initializing its own type, for example:
struct Foo { //... };
struct Bar { //... };
void Default(Foo &obj) {...}
void Default(Bar &obj) {...}
The C++ compiler will know when to call the first or the second overload based on the parameter. The & makes obj a reference to whatever parameter you give it, so any changes made to obj will be reflected to the variable you put as parameter.
Edit:
I also have an idea for how to specify some parameters, you can do it by using default parameters. This is how it works:
For example you the following function; you can specify default values for parameters like this:
void Default (Foo &obj, int number_of_something = 0, int some_other_param = 10)
{ ... }
I have a lot of legacy code that uses a function pointer as an argument of the form double (*f)(double). Now I have a requirement where I need to call this function from a class but function definition uses member variables. What do I do to solve this issue? For example,
void legacy_function(double (*f)(double)) { .... }
class myclass {
double a;
double b;
double c;
void mymethod(...) {
// need to call legacy_function() such that it uses a and b with one unknown
// a+b*x
}
Note that I cannot change definitions or declarations in legacy code.
I hope this is making sense. thanks for suggestions..
There's no clean way to solve this problem. It has no elegant solution within the bounds of the standard language.
One thing you can do is to provide a global or static variable that will serve as this pointer for the intermediate callback wrapper function (see below), and write a static intermediate callback wrapper function which will delecate the call to a non-static class method
class myclass {
...
static myclass *myclass_this;
double callback_wrapper(double d) {
assert(myclass_this != NULL);
return myclass_this->callback(d); // calls the actual implementation
}
};
Also write the actual callback implementation in myclass
class myclass {
...
double callback(double d) {
// do whatever you want with `a`, `b` etc.
return /* whatever */;
}
...
};
Now you can initialize myclass_this and use the intermediate callback wrapper from inside mymethod
...
void mymethod(...) {
myclass_this = this; // initilize the context
legacy_function(&callback_wrapper);
}
...
All this, of course, is terribly inelegant since it relies on global or static variables and therefore is non-reentrant.
There are alternative methods, which all happen to be non-portable and non-standard. (Read about closures and delegates).
I have a function pointer defined by:
typedef void (*EventFunction)(int nEvent);
Is there a way to handle that function with a specific instance of a C++ object?
class A
{
private:
EventFunction handler;
public:
void SetEvent(EventFunction func) { handler = func; }
void EventOne() { handler(1); }
};
class B
{
private:
A a;
public:
B() { a.SetEvent(EventFromA); } // What do I do here?
void EventFromA(int nEvent) { // do stuff }
};
Edit: Orion pointed out the options that Boost offers such as:
boost::function<int (int)> f;
X x;
f = std::bind1st(
std::mem_fun(&X::foo), &x);
f(5); // Call x.foo(5)
Unfortunately Boost is not an option for me. Is there some sort of "currying" function that can be written in C++ that will do this kind of wrapping of a pointer to a member function in to a normal function pointer?
You can use function pointers to index into the vtable of a given object instance. This is called a member function pointer. Your syntax would need to change to use the ".*" and the "&::" operators:
class A;
class B;
typedef void (B::*EventFunction)(int nEvent)
and then:
class A
{
private:
EventFunction handler;
public:
void SetEvent(EventFunction func) { handler = func; }
void EventOne(B* delegate) { ((*delegate).*handler)(1); } // note: ".*"
};
class B
{
private:
A a;
public:
B() { a.SetEvent(&B::EventFromA); } // note: "&::"
void EventFromA(int nEvent) { /* do stuff */ }
};
Run away from raw C++ function pointers, and use std::function instead.
You can use boost::function if you are using an old compiler such as visual studio 2008 which has no support for C++11.
boost:function and std::function are the same thing - they pulled quite a bit of boost stuff into the std library for C++11.
Note: you may want to read the boost function documentation instead of the microsoft one as it's easier to understand
I highly recommend Don Clugston's excellent FastDelegate library. It provides all the things you'd expect of a real delegate and compiles down to a few ASM instructions in most cases. The accompanying article is a good read on member function pointers as well.
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
You may find C++ FAQ by Marshall Cline helpful to what you're trying to accomplish.
Read about pointers to members.
To call a method on the derived class, the method has to be declared in the base class as virtual and overriden in the base class and your pointer should point to the base class method. More about pointers to virtual members.
If you're interfacing with a C library, then you can't use a class member function without using something like boost::bind. Most C libraries that take a callback function usually also allow you to pass an extra argument of your choosing (usually of type void*), which you can use to bootstrap your class, as so:
class C
{
public:
int Method1(void) { return 3; }
int Method2(void) { return x; }
int x;
};
// This structure will hold a thunk to
struct CCallback
{
C *obj; // Instance to callback on
int (C::*callback)(void); // Class callback method, taking no arguments and returning int
};
int CBootstrapper(CCallback *pThunk)
{
// Call the thunk
return ((pThunk->obj) ->* (pThunk->callback))( /* args go here */ );
}
void DoIt(C *obj, int (C::*callback)(void))
{
// foobar() is some C library function that takes a function which takes no arguments and returns int, and it also takes a void*, and we can't change it
struct CCallback thunk = {obj, callback};
foobar(&CBootstrapper, &thunk);
}
int main(void)
{
C c;
DoIt(&c, &C::Method1); // Essentially calls foobar() with a callback of C::Method1 on c
DoIt(&c, &C::Method2); // Ditto for C::Method2
}
Unfortunately, the EventFunction type cannot point to a function of B, because it is not the correct type. You could make it the correct type, but that probably isn't really the solution you want:
typedef void (*B::EventFunction)(int nEvent);
... and then everything works once you call the callback with an obhect of B. But you probably want to be able to call functions outside of B, in other classes that do other things. That is sort of the point of a callback. But now this type points to something definitely in B. More attractive solutions are:
Make B a base class, then override a virtual function for each other class that might be called. A then stores a pointer to B instead of a function pointer. Much cleaner.
If you don't want to bind the function to a specific class type, even a base class (and I wouldn't blame you), then I suggest you make the function that gets called a static function: "static void EventFrom A(int nEvent);". Then you can call it directly, without an object of B. But you probably want it to call a specific instance of B (unless B is a singleton).
So if you want to be able to call a specific instance of B, but be able to call non-B's, too, then you need to pass something else to your callback function so that the callback function can call the right object. Make your function a static, as above, and add a void* parameter which you will make a pointer to B.
In practice you see two solutions to this problem: ad hoc systems where you pass a void* and the event, and hierarchies with virtual functions in a base class, like windowing systems
You mention that boost isn't an option for you, but do you have TR1 available to you?
TR1 offers function, bind, and mem_fn objects based on the boost library, and you may already have it bundled with your compiler. It isn't standard yet, but at least two compilers that I've used recently have had it.
http://en.wikipedia.org/wiki/Technical_Report_1
http://msdn.microsoft.com/en-us/library/bb982702.aspx
It's somewhat unclear what you're trying to accomplish here. what is clear is that function pointers is not the way.
maybe what you're looking for is pointer to method.
I have a set of classes for this exact thing that I use in my c++ framework.
http://code.google.com/p/kgui/source/browse/trunk/kgui.h
How I handle it is each class function that can be used as a callback needs a static function that binds the object type to it. I have a set of macros that do it automatically. It makes a static function with the same name except with a "CB_" prefix and an extra first parameter which is the class object pointer.
Checkout the Class types kGUICallBack and various template versions thereof for handling different parameters combinations.
#define CALLBACKGLUE(classname , func) static void CB_ ## func(void *obj) {static_cast< classname *>(obj)->func();}
#define CALLBACKGLUEPTR(classname , func, type) static void CB_ ## func(void *obj,type *name) {static_cast< classname *>(obj)->func(name);}
#define CALLBACKGLUEPTRPTR(classname , func, type,type2) static void CB_ ## func(void *obj,type *name,type2 *name2) {static_cast< classname *>(obj)->func(name,name2);}
#define CALLBACKGLUEPTRPTRPTR(classname , func, type,type2,type3) static void CB_ ## func(void *obj,type *name,type2 *name2,type3 *name3) {static_cast< classname *>(obj)->func(name,name2,name3);}
#define CALLBACKGLUEVAL(classname , func, type) static void CB_ ## func(void *obj,type val) {static_cast< classname *>(obj)->func(val);}