I'm trying to make a class that can hold and later call functions. It stores the functions in a map along with a string that holds the name of the function.
I tried doing this on Linux with GCC and got the following error: "invalid conversion from void(*)() to void *" on the line functionsMap[nameOfFunction] = func;
Here's the entire program I have so far. It's not done yet, but I'm really curious as to why this would compile under Visual C++ and not GCC. If I'm doing something wrong or could be doing something better, please let me know. Thanks!
#include <iostream>
#include <map>
#include <string>
using namespace std;
class Dyn_Class{
private:
map<string, void *> functionsMap;
public:
Dyn_Class(){}
template<typename ReturnValue>
void add_func( string nameOfFunction, ReturnValue(*func)() ){
functionsMap[nameOfFunction] = func;
}
void remove_func( string nameOfFunction ){
}
Dyn_Class operator()(string nameOfFunction){
}
};
void print(void){
for(int index = 0; index < 9; index++){
cout << index << " ";
}
cout << endl;
}
int main(){
Dyn_Class functionsList;
functionsList.add_func("print", print);
return 0;
}
To have a map of pointers to function taking no arguments and returning void you need:
std::map<std::string, void(*)()> functionsMap;
There is no point making add_func a template as it will only work when instantiated with ReturnValue = void (unless you add a potentially unsafe cast to its implementation).
If your code compiles with Visual C++ it is because Visual C++ is being permissive.
You can pass that function as a parameter like this:
void add(void * f()){...}
How do you pass a function as a parameter in C?
Think on using std::function instead:
class Dyn_Class{
private:
map<string, function<void()> > functionsMap;
public:
Dyn_Class(){}
template<typename FUNC>
void add_func(const string& nameOfFunction, FUNC func){
functionsMap.insert(make_pair(nameOfFunction, func));
}
void remove_func(const string& nameOfFunction ){
}
void operator()(const string& nameOfFunction){
functionsMap[nameOfFunction]();
}
};
Benefits? Using "function", you could use your plain old function pointers, you can use functors or you can use lambda expressions instead:
DynClass dyn;
dyn.add("print", []() { printf("Say hi"; } );
Related
I am coming from c# so please excuse anything I may get wrong in trying to ask this question.
I have created a map that contains a string and a method to handle invoking a method by a string:
//MyClass.h
void SerializeCustomData();
std::unordered_map<std::string, void(MyClass::*)()> functionMap;
MyMethod() {
functionMap["SerializeCustomData"] = &MyClass::SerializeCustomData;
};
My question is; how can I have my map take in a parameter for the method? Either a generic type or a string in c++?
Example:
SerializeCustomData(std::string);
#include <functional>
#include <iostream>
#include <unordered_map>
class MyClass
{
std::unordered_map<std::string, std::function<void(MyClass&, std::string)>> functionMap;
public:
void MyMethod()
{
functionMap.emplace("SerializeCustomData", &MyClass::SerializeCustomData);
}
void CallSerialize()
{
functionMap.at("SerializeCustomData")(*this, "argument");
}
void SerializeCustomData(std::string s)
{
std::cout << "hello: " << s << "\n";
}
};
int main()
{
MyClass c;
c.MyMethod();
c.CallSerialize();
}
Here the function from the map is called with a MyClass& argument and a string. Note that the MyClass isn't bound to the callback, and so we're passing it explicitly.
So this is confusing to explain, but I will try my best.
I have a function one of my classes that takes a function pointer as an argument, and what I would like to do is define the function as part of the argument. ie:
object->setFunctionPointer({string a = ""; return a;});
Is this possible? if so, what is the proper syntax of this?
In C++11, you can do it. You can use C++ lambda (anonymous functions).
See the sample code at http://ideone.com/8ZTWSU
#include <iostream>
using namespace std;
typedef const char * (*funcptr)();
funcptr s;
void setFuncPtr(funcptr t)
{
s = t;
}
int main() {
// your code goes here
setFuncPtr([]{return "Hello \n"; });
printf("%s\n", s());
return 0;
}
If we are talking about C++ you should use std::function and not function pointers. Unless you are interfacing with C APIs.
class Foo{
SetFunc(std::function<void(int)> func)
{
m_func = func;
}
private:
std::function<void(int)> m_func;
};
If your function is a member of a class, you cannot take an ordinary function pointer to store its address. What you need is a delegate; which are specialised function pointers for methods. Search the internet for C++ delegate and you should find numerous examples.
(Note: maybe there is an exception for static methods; I don't remember.)
Here is a complete example. Since c++11 this is the way to go:
#include<functional>
#include<string>
#include<iostream>
using namespace std;
class Object
{
public:
void setFunctionPointer(function<string(void)> function)
{
m_function = function;
}
string run()
{
return m_function();
}
private:
function<string(void)> m_function;
};
int main(int argc, char**argv)
{
Object *object = new Object;
object->setFunctionPointer([]{string a = "FOO"; return a;}); // here is the function assignment
cout << object->run() << endl;
delete object;
}
When run this prints FOO to stdout.
I'm storing a map in a class that has strings as keys and pointers to member functions as values. I'm having trouble calling the right function throw the function pointer.
Here is the code:
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Preprocessor;
typedef void (Preprocessor::*function)();
class Preprocessor
{
public:
Preprocessor();
~Preprocessor();
void processing(const string before_processing);
private:
void take_new_key();
map<string, function> srch_keys;
string after_processing;
};
Preprocessor::Preprocessor()
{
srch_keys.insert(pair<string, function>(string("#define"), &Preprocessor::take_new_key));
}
Preprocessor::~Preprocessor()
{
}
void Preprocessor::processing(const string before_processing)
{
map<string, function>::iterator result = srch_keys.find("#define");
if(result != srch_keys.end())
result->second;
}
void Preprocessor::take_new_key()
{
cout << "enters here";
}
int main()
{
Preprocessor pre;
pre.processing(string("...word #define other word"));
return 0;
}
In function Preprocessor::processing if the string is found in the map then, I call the proper function. The problem is that, in this code, Preprocessor::take_new_key is never called.
Where is the mistake ?
Thanks
The correct syntax is this:
(this->*(result->second))();
That is ugly. So lets try this:
auto mem = result->second; //C++11 only
(this->*mem)();
Use whichever makes you happy.
result->second does not call the function pointer. Try ((*this).*result->second)();
I have the following problem. I have a function from an external library (which cannot be modified) like this:
void externalFunction(int n, void udf(double*) );
I would like to pass as the udf function above a function member of an existing class. Please look at the following code:
// External function (tipically from an external library)
void externalFunction(int n, void udf(double*) )
{
// do something
}
// User Defined Function (UDF)
void myUDF(double* a)
{
// do something
}
// Class containing the User Defined Function (UDF)
class myClass
{
public:
void classUDF(double* a)
{
// do something...
};
};
int main()
{
int n=1;
// The UDF to be supplied is myUDF
externalFunction(n, myUDF);
// The UDF is the classUDF member function of a myClass object
myClass myClassObj;
externalFunction(n, myClassObj.classUDF); // ERROR!!
}
I cannot declare the classUDF member function as a static function, so the last line of the code above results in a compilation error!
This is impossible to do - in c++, you must use either a free function, or a static member function, or (in c++11) a lambda without capture to get a function pointer.
GCC allows you to create nested function which could do what you want, but only in C. It uses so-called trampolines to do that (basically small pieces of dynamically generated code). It would be possible to use this feature, but only if you split some of the code calling externalFunction to a separate C module.
Another possibility would be generating code at runtime eg. using libjit.
So if you're fine with non-reenrant function, create a global/static variable which will point to this and use it in your static function.
class myClass
{
public:
static myClass* callback_this;
static void classUDF(double* a)
{
callback_this.realUDF(a);
};
};
Its really horrible code, but I'm afraid you're out of luck with such a bad design as your externalFunction.
You can use Boost bind or TR1 bind (on recent compilers);;
externalFunction(n, boost::bind(&myClass::classUDF, boost::ref(myClassObj)));
Unfortunately, I lived in a pipe dream for the last 10 minutes. The only way forward is to call the target using some kind of a static wrapper function. The other answers have various neat (compiler-specific) tidbits on that, but here's the main trick:
void externalFunction(int n, void (*udf)(double*) )
{ double x; udf(&x); }
myClass myClassObj;
void wrapper(double* d) { myClassObj.classUDF(d); }
int main()
{
externalFunction(1, &wrapper);
}
std::function<>
Store a bound function in a variable like this:
std::function<void(double*)> stored = std::bind(&myClass::classUDF, boost::ref(myClassObj))
(assuming C++0x support in compiler now. I'm sure Boost has a boost::function<> somewhere)
Vanilla C++ pointers-to-member-function
Without magic like that, you'd need pointer-to-memberfunction syntax:
See also live on http://ideone.com/Ld7It
Edit to clarify to the commenters, obviously this only works iff you have control over the definition of externalFunction. This is in direct response to the /broken/ snippet int the OP.
struct myClass
{
void classUDF(double* a) { };
};
void externalFunction(int n, void (myClass::*udf)(double*) )
{
myClass myClassObj;
double x;
(myClassObj.*udf)(&x);
}
int main()
{
externalFunction(1, &myClass::classUDF);
}
C++98 idiomatic solution
// mem_fun_ref example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
int main ()
{
std::vector<std::string> numbers;
// populate vector:
numbers.push_back("one");
numbers.push_back("two");
numbers.push_back("three");
numbers.push_back("four");
numbers.push_back("five");
std::vector <int> lengths (numbers.size());
std::transform (numbers.begin(), numbers.end(), lengths.begin(),
std::mem_fun_ref(&std::string::length));
for (int i=0; i<5; i++) {
std::cout << numbers[i] << " has " << lengths[i] << " letters.\n";
}
return 0;
}
Here is how I do this, when MyClass is a singleton:
void externalFunction(int n, void udf(double) );
class MyClass
{
public:
static MyClass* m_this;
MyClass(){ m_this = this; }
static void mycallback(double* x){ m_this->myrealcallback(x); }
void myrealcallback(double* x);
}
int main()
{
MyClass myClass;
externalFunction(0, MyClass::mycallback);
}
#include <boost/bind.hpp>
#include <iostream>
using namespace std;
using boost::bind;
class A {
public:
void print(string &s) {
cout << s.c_str() << endl;
}
};
typedef void (*callback)();
class B {
public:
void set_callback(callback cb) {
m_cb = cb;
}
void do_callback() {
m_cb();
}
private:
callback m_cb;
};
void main() {
A a;
B b;
string s("message");
b.set_callback(bind(A::print, &a, s));
b.do_callback();
}
So what I'm trying to do is to have the print method of A stream "message" to cout when b's callback is activated. I'm getting an unexpected number of arguments error from msvc10. I'm sure this is super noob basic and I'm sorry in advance.
replace typedef void (*callback)(); with typedef boost::function<void()> callback;
A bound function doesn't produce an ordinary function, so you cannot just store it in a regular function pointer. However, boost::function is able to handle anything as long as it is callable with the correct signature, so that's what you want. It will work with a function pointer, or a functor created with bind.
After a few corrections to your code, I came up with this:
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
// i prefer explicit namespaces, but that's a matter of preference
class A {
public:
// prefer const refs to regular refs unless you need to modify the argument!
void print(const std::string &s) {
// no need for .c_str() here, cout knows how to output a std::string just fine :-)
std::cout << s << std::endl;
}
};
// holds any arity 0 callable "thing" which returns void
typedef boost::function<void()> callback;
class B {
public:
void set_callback(callback cb) {
m_cb = cb;
}
void do_callback() {
m_cb();
}
private:
callback m_cb;
};
void regular_function() {
std::cout << "regular!" << std::endl;
}
// the return type for main is int, never anything else
// however, in c++, you may omit the "return 0;" from main (and only main)
// which will have the same effect as if you had a "return 0;" as the last line
// of main
int main() {
A a;
B b;
std::string s("message");
// you forget the "&" here before A::print!
b.set_callback(boost::bind(&A::print, &a, s));
b.do_callback();
// this will work for regular function pointers too, yay!
b.set_callback(regular_function);
b.do_callback();
}