#define function arguments c++ - c++

I have a set of functions called in a common interface, and I store those function pointers in a common container, so I have
typedef void(*CommandFunction)(const InputArgsMap &, const ArgumentMap *);
With this said, what is the best way to declare functions of this type without copy-pasting the argument list? I thought of implementing this via a #define, but is there any other (better, oop) way?
For instance, is it possible to do something like
#define CMD_ARGS (const InputArgsMap &, const ArgumentMap *)
void _fcn_1(CMD_ARGS);
void _fnc_2(CMD_ARGS);

If you declare a function, rather than pointer, type alias
typedef void CommandFunction(const InputArgsMap &, const ArgumentMap *);
then you can use it to declare functions
CommandFunction _fcn_1;
CommandFunction _fcn_2;
You'll still need to write out the parameter list when you define them.
is there any other (better, oop) way?
Overriding a virtual member function of an abstract interface might be nicer, depending on exactly what you're doing. You will have to duplicate the parameter list if you do that, which you seem to find distasteful; but in modern C++ you can at least use the override specifier to make sure you get that right.

Related

C++ runtime member function access by string name

I have two classes:
class MyClassInfo {
public:
void AddMethod(std::string name, void* pointer); // I don't know what signature should be
}
class MyClass
{
public:
void SetField1(int f1);
int GetFileld1();
private:
int field1;
};
I need to be able to access the methods of MyClass by name (string) during runtime. I don't want to use any libraries (except boost) and/or compiler functionality (such as rtti) to do that.
I don't know which signature I should use in AddMethod method, because I don't know how to transmit the function pointer to the function. This function must be a universal function which allows to add any method. Maybe you know a better variant how to do that without MyClassInfo. Any help will be appreciated.
That is not possible in directly C++. You will have to look at alternatives like creating a map of names to member function pointers. But even that would require consistent method signatures.
Something like
std::map<std::string, int (MyClass::*)(void*))
for instance. Your AddMethod signature would then look like this
void AddMethod(std::string name, int (MyClass::* pointer)(void*));
and you would call it like this
info.AddMethod("someMethod", &MyClass::someMethod);
If all functions you want to pass through AddMethod have the same signature (possibly after binding some of the arguments), you can use this signature:
void AddMethod(std::string name, boost::function<int ()> func);
and use like this:
info.AddMethod("GetFileId1", std::bind1st(std::mem_fun(&MyClass::GetFileId1), &MyClassInstance);
If the functions have different signatures, you could store them using boost::function_base:
void AddMethod(std::string name, boost::function_base func);
and you use it like above. The challenge is now to find out exactly what type is stored in the boost::function object so you can use it.

C++ function pointer casting

I'm developing a templated binary search tree in C++ for a data structures class right now. Everything has been going well until now. This issue deals with some nitty gritty C++ stuff that I'm not to familiar with, and I need help.
I've previously defined functions that traverse the tree and visit each node in different orders. The one in question here is defined as follows.
TreeNode.h
public:
static void PostOrderVisit(TreeNode<T>* node, void visit(const T& v));
TreeNode.cpp
template <class T> void TreeNode<T>::PostOrderVisit(TreeNode* node, void visit(const T& v)) {
if (node->leftChild != NULL)
PostOrderVisit(node->leftChild, visit);
if (node->rightChild != NULL)
PostOrderVisit(node->rightChild, visit);
visit(node->value);
}
This works fine in a test program that makes nodes and statically calls PostOrderVisit.
In a friend class (BinSTree.h/cpp), I am implementing a method that deletes every node in the tree, so I thought it would be a good idea to use this visitor and call my Delete() function on each node (the Delete() function also works fine in test programs for the BinSTree).
This function is defined as follows.
template <class T> void BinSTree<T>::ClearTree() {
TreeNode<T>::PostOrderVisit(this->root(), &BinSTree<T>::Delete);
}
And here lies the problem. g++ says...
BinSTree.cpp:156: error: no matching function for call to ‘TreeNode<int>::PostOrderVisit(TreeNode<int>*, void (BinSTree<int>::*)(const int&))’
TreeNode.cpp:56: note: candidates are: static void TreeNode<T>::PostOrderVisit(TreeNode<T>*, void (*)(const T&)) [with T = int]
In this case, I thought that void (BinSTree<T>::*)(const T&) would be an instance of void (*)(const T&), but it is not. The only way I can get the call to be recognized by the function definition is by casting the function pointer like this:
TreeNode<T>::PostOrderVisit(this->root(), (void (*)(const T& v)) &BinSTree<T>::Delete);
This recognizes the function and calls it appropriately, however (this took some significant research...), C++ member functions have an implicit parameter that allows the 'this' keyword to be accessed from within. Casting a member function pointer to a plain function pointer drops the 'this' reference altogether, causing my Delete() method to seg fault (it uses 'this' quite a bit).
This has been a HELL of a hassle, and I have spent quite a bit of time on such a small bit of this project. Can anyone show me a way to either A: make the function be recognized without the casting, or B: how to maintain the 'this' reference throughout the cast. The ClearTree() and Delete() methods are both within the same class.
Thanks in advance.
First of all, PostOrderVisit should take the function argument as a pointer, i.e. PostOrderVisit(TreeNode<T>* node, void (*visit)(const T& v)).
However, that wont solve your problem because you are passing it a non-static member function. Either the function you pass to it has to be static in the class, or you can use something like std::function instead of a function pointer argument, i.e. PostOrderVisit(TreeNode<T>* node, std::function<void(const T&)> visit).
Edit
In that case I think you have two ways you can do this: One is to change your design to fit the parameter, that means you can not use member methods as a parameter. The second is to change the code to fit your design, and explain to the teacher that you had to change the interface due to its limitations, and explain those limitations.
The problem with using a normal function pointer as argument is that member functions have an implicit and hidden argument, this, for the instance of the class. Normal functions do not have this hidden parameter, and so the compiler prohibits you from using a member function. The solution is to either use normal functions, which is not very C++-ish, another is to use static member functions (as they don't have a this pointer), or use something like std::function.
As for how to use std::function, you use it in the declaration and definition of PostOrderVisit like I've shown. When you call it you do something like this:
template <class T> void BinSTree<T>::ClearTree() {
TreeNode<T>::PostOrderVisit(this->root(), std::mem_fn(&BinSTree<T>::Delete));
}
Non-static methods take an implicit parameter for "this". E.g. for a method C::f(int i), you can think of it like f(C* this, int i). Any casting that you do and screws up this signature you can expect badness to happen. You have already experienced crashes but more sinister artifacts could make the program misbehave or crash at other seemingly random places.
You can use pointer to member function like this:
in .h
template <class C>
static void PostOrderVisit(C* node, void (C::* visit)(const T& v));
in .cpp (actually if it is a template it has all to be in h, otherwise link error)
template <class T>
template <class C>
void TreeNode<T>::PostOrderVisit(C* node, void (C::* visit)(const T& v))
{
// ...
T value;
(node->*visit)(value);
// ...
}
You either pass pointer to your derived class (C as in here) or pointer to base class (TreeNode as in original). At some point you may need to cast.
You can also leave original function for when you pass a normal function as visitor. Function overload would take care.
A more generic way can be to use std::function. Although it may have some minor performance hit it would be most generic.
e.g. (have not compiled may have some minor syntax errors):
static void PostOrderVisit(TreeNode<T>* node, std::function<void (const T& v)> visit);
Inside PostOrderVisit you just do visit(value), e.g. call like normal function.
When you call PostOrderVisit you can use all the power of std::bind or boost::bind to carry as much extra info as you wish. E.g.
PostOrderVisit(this->root(), std::bind(&BinSTree::Delete, this));

C++: member function address (function pointers)

I have a class X which has this method:
void setRxHandler(void (*h)(int));
And I want to pass to it a member function that exists in instances of class Y.
void comm_rxHandler(int status);
I tried the following:
x.setRxHandler(comm_rxHandler)
But it get the following compile error (I'm using Qt):
error: no matching function for call to
‘X::setRxHandler(< unresolved overloaded function type>)’
So, how can I do that?
I noticed if I declare comm_rxHandler (class Y) as static, I have no errors. But I want comm_rxHandler as a non-static method. Also I want setRxHandler method (class X) to be generic and not class-specific. So I can't declare that method as:
setRxHandler(void (Y::*h)(int))
How to do that? Can you help me on this?
Thanks!
C++ doesn't support bound methods. To invoke a member function through a function pointer, you need to have two things: an instance of the class and the function pointer.
So setRxHandler(void (Y::*h)(int)) is almost correct. You need to declare it as:
void setRxHandler(Y*, void (Y::*h)(int));
To invoke setRxHandler(), you need to pass it arguments as follows:
Y y;
setRxHandler(&y, &Y::comm_rxHandler);
In the setRxHandler() method, you can invoke the function pointer using this syntax:
void setRxHandler ( Y* y, void (Y::*h)(int) )
{
// ...
(y->*h)(0);
// ...
}
To make generic, you need to abstract the Y parameter away, but this is difficult to get right. Check out Boost.Function for an existing implementation that supports this use case, and many more.
Change your callback to this:
void setRxHandler(std::function(<void(int)>);
Then you can use binders:
setRxHandler( std::bind(&class_name::comm_rxHandler, obj) );
(std::function and std::bind are part of the upcomming next version of the C++ standard. It's quite likely your compiler already comes with them. If not, they might live in namespace std::tr1. If all else fails, you will find them at boost - which is where they were invented - as boost::function and boost::bind.)
You can, however, also pass non-member or static functions to setRxHandler, as well as function objects (which is the result of std::bind).
If your compiler already supports lambda functions (also part of the next standard, but already supported by, e.g., recent versions of GCC and VC), you can also use one of those:
setRxHandler( [](){obj.comm_rxHandler();} );
As it is now, the setRxHandler prototype takes a pointer to a function that doesn't return anything and takes an int. As you have noticed, this won't work with member functions because they can't be called like a normal function (you have to handle the this pointer as well, which means having an instance of that class to call the method on).
To make it both work with member functions and non-specific (generic), you have to either make a base class and have all classes you want to use setRxHandler with derive from that class:
class Base { ... };
class Derived : public Base { ... };
// then for the prototype
void setRxHandler(void (Base::*h)(int)) { ... }
// and you can use setRxHandler for all types that derive from Base, which gives you more control than the second option, which is:
or use templates:
template<typename T>
void setRxHandler(void (T::*h)(int)) { ... }
With the template option, you really have no control over what class will be used with setRxHandler (excluding RTTI), which can be exactly what you want.
You can either make a base class for Y and use that (to avoid being "class specific"), or use templates:
template <class T>
setRxHandler(void (T::*h)(int));
But then this may raise questions of how to use the member function (you tell us if it does).
As others have already mentioned, C++ does not provide this functionality.
Another option you could use is libsigc++ which is widely used in gtkmm, see this example in their tutorial for instance on how to pass pointers to member-functions. Your example could look something like:
// sigc::slot<void, int> is a 'slot' to hold a function with return type void
// and 1 int argument.
void setRxHandler(sigc::slot<void, int> slot);
void comm_rxHandler(int status);
//sigc::mem_fun() can convert a member function to a function slot.
x.setRxHandler(sigc::mem_fun(*this, &X::comm_rxHandler));

Is it possible to declare void pointer to a template function in C++?

Is it possible?
If as I have understood is correct, void pointer can point to any type. Therefore, a template function (undeclared type) is possible? or void pointer is only reserve for "variable" not function? Then what about void function pointer?
You can cast any function pointer type to any other, but you'd better cast it to the right type before you call it. You can therefore use void(*)() as an equivalent to void* for function pointers. This also works with function templates.
template<typename T>
void f(T){}
typedef void(*voidfp)();
voidfp fp=static_cast<voidfp>(&f<int>); // store address of f(int) in variable
static_cast<void(*)(int)>(fp)(3); // call the function
fp=static_cast<voidfp>(&f<std::string>); // store address of f(std::string) in variable
static_cast<void(*)(std::string)>(fp)("hello"); // call the function
According to the Standard, a void* is not required to be able to hold a function pointer. (It is required to hold a pointer to any kind of data). However, most cpu architectures you're likely to see these days have data pointers & function pointers that are the same size.
There is an issue here, because of the words used I am afraid.
There is a difference between pointers and function pointers, most notably they need not be the same size.
Therefore it is undefined behavior to use void* type to hold the address of a function pointer.
In general it is not a good idea in C++ to use void*. Those are necessary in C because of the lack of a proper type system but C++ type system is much more evolved (even though not as evolved as recent languages).
You could probably benefit from some objectification here. If you make your method an instance of a class (template) you can have this class derived from a common base class. This is quite common, those objects are called Functors.
However, without a precise description of your issue, it'll be hard to help more.
to do this with templates you need some trickery, else the compiler cannot disambiguate the function (this is really not recommended, its horrible to read, and probably violates a few thousand porgamming best practices)
IE: this does not work (atleast under VS08 & GCC 3.5):
template <typename tType> tType* GetNULLType()
{
return static_cast<tType*>(0);
}
void* pf = static_cast<void*>(GetNULLType<int>);
you instead need to do:
template <typename tType> tType* GetNULLType()
{
return static_cast<tType*>(0);
}
typedef int* (*t_pointer)();
t_pointer pfGetNull = GetNULLType<int>;
void* pfVoid = (void*)(pfGetNull);
(and before purists moan, it seems C++ style 'safe' casting will not allow this)

Arrays of function pointers as members of classes

Can I have, as a private member of a class, an array of function pointers? Something like,
class MyClass {
public: //public stuff
private:
void (*specficFunctions[16]) (void);
}
I specifically don't want to use functors or functionoids.
Yes, though you usually want to use a typedef to keep the syntax a bit more manageable:
class MyClass {
typedef void (*fptr)(void);
fptr SpecificFunctions[16];
};
Note, however, that these are pointers to global functions, not member functions.
There's nothing special about function pointers. The declaration syntax may be confusing (which can be mitigated with typedefs) but they're not really different from any other pointer. If you can make an array of pointers, you can make an array of function pointers. There's also nothing special about a private member of a class compared with any other type of variable. If you can make an array, you can make an array a private member of a class.
Yes. (You can always answer this kind of question by trying to compile such code.)