I am begginer in C++ and
I have the following template class:
template<typename... extensions>
class SomeServiceProxy
{
public:
void DoSomething() {std::cout<<"\ndoing sth\n";};
};
With the following pointer to function using "using" keyword
template<typename... extensions>
using DoSomethingFnPtr = void (SomeServiceProxy<extensions...>::*)();
And I am trying to put the method in a map and call it:
std::map<int, void*> myMap;
int main()
{
SomeServiceProxy<int> proxy;
DoSomethingFnPtr<int> memfnptr = &SomeServiceProxy<int>::DoSomething;
proxy.DoSomething();
(proxy.*memfnptr)(); //works
myMap[0]= &memfnptr;
auto it=myMap.find(0);
if(it != myMap.end() ){
SomeServiceProxy<int> proxy2;
(proxy2.&(it->second))(); //error
}
std::cout<<endl;
return 0;
}
What I get is : error: expected unqualified-id before ‘&’ token
Q: Is there any way to call the method using the map?
A void* is not a member function pointer. And memfnptr is a member function pointer, you should store it in the map rather than a pointer to it.
This is your code made to compile with the most obvious fixes:
#include <map>
#include <iostream>
template<typename... extensions>
class SomeServiceProxy
{
public:
void DoSomething() {std::cout<<"\ndoing sth\n";};
};
template<typename... extensions>
using DoSomethingFnPtr = void (SomeServiceProxy<extensions...>::*)();
std::map<int, DoSomethingFnPtr<int>> myMap;
int main()
{
SomeServiceProxy<int> proxy;
DoSomethingFnPtr<int> memfnptr = &SomeServiceProxy<int>::DoSomething;
proxy.DoSomething();
(proxy.*memfnptr)(); //works
myMap[0]= memfnptr;
auto it=myMap.find(0);
if(it != myMap.end() ){
SomeServiceProxy<int> proxy2;
(proxy2.*(it->second))(); //error
}
std::cout<<std::endl;
return 0;
}
I suppose you want to store member function pointers for different instantiations of SomeServiceProxy in the same map and thats why you used void*. There are much better ways to do type erasure than using void*, though what is more or less universal with type erasure is: Erasing the type is the easy part. The difficult part is to restore the type when you need it. When you store member function pointers for different instantiations of SomeServiceProxy in the same map then you can only call them when you know what instantiation of the template it is.
The simple solution is to use a std::map<int, std::function<void()>> then store lambdas (or some other functor) that encapsulates the instance and the member function to be called. For example:
std::map< int , std::function<void()>> mymap;
mymap[0] = []() {
SomeServiceProxy<int> proxy;
proxy.DoSomething();
};
mymap[0]();
Related
This question answers how to do it for a regular unordered_map, but what about the member one? The IDE reports the error in the comment. opcodes maps characters to pointers to functions, which should be called on behalf of concrete instances. Also I wonder if it's possible to make it constexpr.
// Foo.cpp
class Foo {
public:
void execute(char c) { (*opcodes[c])(); }
void operation1()
{
// Do something with value_
}
void operation2();
private:
typedef void (*operation)();
static const std::unordered_map<char, operation> opcodes{
{'1', &Foo::operation1},
{'2', &Foo::operation2}
}; // No matching constructor for initialization of 'const std::unordered_map<char, operation>' (aka 'const unordered_map<char, void (*)()>')
int value_;
}
// main.cpp
int main()
{
Foo foo;
foo.execute('1');
return 0;
}
How to create a member unordered_map with values of pointers to functions?
Like this:
struct example {
using fun = return_type(/*arg types*/);
std::unordered_map<key_type, fun*> map;
};
typedef void (*operation)();
static const std::unordered_map<char, operation> opcodes{
{'1', &Foo::operation1},
{'2', &Foo::operation2}
}
The problem with this is that you have a map of pointers function, but you try to initialise with pointers to member functions. A pointer to member function is not a pointer to function and cannot be converted to a pointer to function.
So, what you need is a map of pointers to member functions instead:
using operation = void (Foo::*)();
Or, you need to not be using non-static member functions.
And how to call the [pointer to member] function after getting it from map?
Example:
(this->*opcodes.at('1'))();
I'm trying to write a program which creates a class that contains vector of pointers to member functions, with add() and remove() member functions.
The code I wrote is -
#include <iostream>
#include <vector>
using namespace std;
typedef void(*classFuncPtr)();
class FunctionVectors
{
private:
vector<classFuncPtr> FunctionPointerVector;
public:
FunctionVectors(){}
void add(classFuncPtr funcPtr);
void remove(int index);
void run();
void a(){cout<<"a: Why are you calling me?"<<endl;}
};
void FunctionVectors::add(classFuncPtr funcPtr)
{
FunctionPointerVector.push_back(funcPtr);
}
void FunctionVectors::remove(int index)
{
FunctionPointerVector.erase(FunctionPointerVector.begin() + index);
}
int main()
{
FunctionVectors f;
classFuncPtr fv = &(classFuncPtr)FunctionVectors::a; // error here
f.add(fv);
f.run();
return 0;
}
But, it is showing error in line# 32 -
error C2440: 'type cast' : cannot convert from 'void (__thiscall FunctionVectors::* )(void)' to 'classFuncPtr'
Please, tell me how should I modify it to work properly.
typedef void(*classFuncPtr)();
This is not a pointer to method, but a pointer to function. Method differs from function, because it's being called in a context: requires this to work correctly.
Keep in mind, that in C++ you are only able to create vector of pointers to a method of specific class. So you won't be able to keep pointers to two methods of different classes in that vector.
The solution - as suggested in comments - is to use std::function or boost::function and possibly C++11 lambdas, because they provide a lot more flexibility than simple pointer-to-members.
If you want to implement an event mechanism, consider also using functors instead of methods:
Create base class for event handler:
class MyEventHandler
{
public:
virtual void operator()(void * sender, int data) = 0;
}
Create simple vector of these:
std::vector<MyEventHandler *> MyEvent;
Create specific handlers in your classes:
class MyClass
{
private:
class SpecificEventHandler : MyEventHandler
{
public:
void operator()(void * sender, int data)
{
std::cout << "Event handled!";
}
}
public:
SpecificEventHandler Handler;
MyClass()
{
}
}
Hook the handler to your event:
MyEvent.push_back(&(myClassInstance.Handler));
Code written from memory, may not compile, but you should get the idea.
std::function< void() >
looks like the signature you are looking for. If it isn't available in your version of C++ but you can use boost, then you fill find it in boost. Look up documentation for appropriate header, for std, for function.
To create one for a member function, you need to bind it, and to bind it to FunctionVectors::a() you will need an instance of a FunctionVectors to call it on.
In your example, I will make the typedef for you
typedef std::function< void() > classFuncPtr; // in reality a badly named typedef
int main()
{
FunctionVectors f;
classFuncPtr fv = std::bind( &FunctionVectors::a, f );
}
alternatively if you really have C++11 with lambdas you can do
classFuncPtr = [ f ]() { f.a() );
In your case I reckon you don't really want a free function, you always want a member function of your class you want.
typedef void (*FunctionVectors::classFuncPtr )();
and you would use
(this->*func)();
to invoke it
I'm implementing a generic setting reader.
The idea is that I have an application which settings can be boolean, integers and strings.
Then I have a Config class where the getters for such settings are implemented, the config class takes a customer in the constructor, so that it knows it will read settings for that very customer.
I'm having troubles in having that working, I think I am misusing boost::function confusing it with plain function pointer.
In the maps I'd like to have references while the boost::function shall be binded only at config read time since there I have allocated a Config instance for the given customer.
The problem is that I cannot use function pointers without typedefs and this complicates the template work, any wiser solution ?
#include "Config.h"
class ConfigReader
{
ConfigReader();
template<class R>
R readConfig(std::string customer, std::string settingName);
private:
typedef bool (Config::* BoolConfigFunctor) () const;
std::map<std::string, BoolConfigFunctor> boolConfigMap;
typedef int(Config::* IntConfigFunctor) () const;
std::map<std::string, IntConfigFunctor> integerConfigMap;
typedef std::string (Config::* StrConfigFunctor) () const;
std::map<std::string, StrConfigFunctor> stringConfigMap;
template<class R>
std::map<std::string, R (Config::* ) () > getConfigMap();
}
ConfigReader()
{
// INIT all settings you want to be readable in the functor maps
boolConfigMap["USE_NEW_VERSION"] = &Config::useNewVersion;
boolConfigMap["MAINTENANCE_MODE"] = &Config::isMaintenance;
integerConfigMap["TIMEOUT"] = &Config::getTimeout;
stringConfigMap["USERNAME"] = &Config::getUserName;
...
}
template<class R>
R readConfig(std::string customer, std::string settingName)
{
R returnValue;
typedef typename std::map<AMD_STD::string, R (Config::* ) () > ConfigMap_t;
typedef typename ConfigMap_t::const_iterator ConfigMapIter_t;
ConfigMap_t configMap = getConfigMap<R>();
ConfigMapIter_t configIter = configMap.find(settingName);
if (configIter != configMap.end())
{
Config config(customer); // Real instance of Config against which we want to call the function
boost::function<R ()> configFunction;
configFunction =
boost::bind(
configIter->second,
config);
returnValue= configFunction();
}
return returnValue;
}
template<>
std::map<std::string, bool (Config::* ) ()> ConfigReader::getConfigMap()
{
return boolConfigMap;
}
template<>
std::map<std::string, int (Config::* ) ()> ConfigReader::getConfigMap()
{
return integerConfigMap;
}
template<>
std::map<std::string, string (Config::* ) ()> ConfigReader::getConfigMap()
{
return stringConfigMap;
}
UPDATE
it did work by using function references in maps rather than boost::function
You can't use member function pointers as normal function pointers, unless the member functions are static. You should instead use Boost bind with a specific object instance:
boolConfigMap["USE_NEW_VERSION"] = boost::bind(&Config::useNewVersion, someInstanceOfConfig);
The reason that (non-static) member function pointers are not the same as normal function pointers (or static member function pointers) is that member functions have a hidden "zeroeth" argument, that is the this pointer inside the member function.
Also, your declaration of the boost::function objects should be only e.g.
boost::function<bool()>
That will handle all type of functions returning a bool and taking no arguments.
If your compiler is new enough, you might also want to change to be using std::function and std::bind.
After your edit to show with member function pointers: You have to call the function pointers correctly as well, like
(config.*configIter->second)();
I need a table that maps codes to C++ member functions. Suppose we have this class:
class foo
{
bool one() const;
bool two() const;
bool call(char*) const;
};
What I want is a table like this:
{
{ “somestring”, one },
{ ”otherstring”, two }
};
So that if I have a foo object f, f.call(”somestring”) would look up “somestring” in the table, call the one() member function, and return the result.
All of the called functions have identical prototypes, i.e., they are const, take no parameters, and return bool.
Is this possible? How?
Yes, it's possible, using pointer to member syntax.
Using the prototypes you supplied, the map would be.
std::map< std::string, bool( foo::*)() const>
It would be called with this syntax
this->*my_map["somestring"]();
That odd-looking ->* operator is for pointer to member functions, which can have some odd considerations, due to inheritance. (It's not just a raw address, as -> would expect)
Since you only need to store members of the same class, with the same arguments and return types, you can use pointer-to-member-functions:
bool foo::call(char const * name) const {
static std::map<std::string, bool (foo::*)() const> table
{
{"one", &foo::one},
{"two", &foo::two}
};
auto entry = table.find(name);
if (entry != table.end()) {
return (this->*(entry->second))();
} else {
return false;
}
}
That uses the new initialisation syntax of C++11. If your compiler doesn't support it, there are various other options. You could initialise the map with a static function:
typedef std::map<std::string, bool (foo::*)() const> table_type;
static table_type table = make_table();
static table_type make_table() {
table_type table;
table["one"] = &foo::one;
table["two"] = &foo::two;
return table;
}
or you could use Boost.Assignment:
static std::map<std::string, bool (foo::*)() const> table =
boost::assign::map_list_of
("one", &foo::one)
("two", &foo::two);
or you could use an array, and find the entry with std::find_if (or a simple for loop if your library doesn't have that yet), or std::binary_search if you make sure the array is sorted.
Yes.
struct foo_method
{
std::string name;
bool (foo::*pfun)() const;
};
foo_method methodTable[] =
{
{ “somestring”, &foo::one },
{ ”otherstring”, &foo::one }
};
void foo::call(const char* name) const
{
size_t size = sizeof(methodTable)/sizeof(*methodTable);
for(size_t i = 0 ; i < size ; ++i)
{
if ( methodTable[i].name == name )
{
bool (foo::*pfun)() const = methodTable[i].pfun;
(this->*pfun)(); //invoke
}
}
}
I would go with boost::function with std::map. Concretely, something like this :
typedef boost::function<bool()> MyFunc;
typedef std::map<std::string, MyFunc> MyFuncMap;
Then, given an instance of MyFuncMap, you could just do map["something"](). Then you could wrap that in a class that overloads operator(). You could use function pointers/references, but I prefer using boost::function because it allows me to bind pointers to member functions (using boost::bind) or use other function objects. You can also test boost::function in conditionals as you would with regular function pointers.
Here is the relevant documentation :
Boost.Function
Boost.Bind
Good luck!
Edit: Regarding your question about the const member and boost::function, here's an example :
#include <boost/function.hpp>
#include <boost/bind.hpp>
typedef boost::function<bool ()> FuncPtr;
struct Test
{
bool test() const
{
std::cout << "yay" << std::endl;
}
};
int main(int argc, char **argv)
{
Test t;
FuncPtr ptr = boost::bind(&Test::test, &t);
ptr();
}
I'd just like to add that a pointer to a member function is meaningless without having an instance of a class on which to call it. The situation you've described accounts for this (and I think you know this), however in other situations, it may be necessary to encapsulate the function pointer with a pointer or reference to the instance to which it corresponds in some sort of functor construct.
I want to fill a map with class name and method, a unique identifier and a pointer to the method.
typedef std::map<std::string, std::string, std::string, int> actions_type;
typedef actions_type::iterator actions_iterator;
actions_type actions;
actions.insert(make_pair(class_name, attribute_name, identifier, method_pointer));
//after which I want call the appropriate method in the loop
while (the_app_is_running)
{
std::string requested_class = get_requested_class();
std::string requested_method = get_requested_method();
//determine class
for(actions_iterator ita = actions.begin(); ita != actions.end(); ++ita)
{
if (ita->first == requested_class && ita->second == requested_method)
{
//class and method match
//create a new class instance
//call method
}
}
}
If the method is static then a simple pointer is enough and the problem is simple,
but I want to dynamically create the object so I need to store a pointer to class and an offset for the method and I don't know if this works (if the offset is always the same etc).
The problem is that C++ lacks reflection, the equivalent code in a interpreted language with reflection should look like this (example in PHP):
$actions = array
(
"first_identifier" => array("Class1","method1"),
"second_identifier" => array("Class2","method2"),
"third_identifier" => array("Class3","method3")
);
while ($the_app_is_running)
{
$id = get_identifier();
foreach($actions as $identifier => $action)
{
if ($id == $identifier)
{
$className = $action[0];
$methodName = $action[1];
$object = new $className() ;
$method = new ReflectionMethod($className , $methodName);
$method -> invoke($object);
}
}
}
PS: Yes I'm trying to make a (web) MVC front controller in C++.
I know I know why don't use PHP, Ruby, Python (insert your favorite web language here) etc?, I just want C++.
Perhaps you're looking for member function pointers.
Basic usage:
class MyClass
{
public:
void function();
};
void (MyClass:*function_ptr)() = MyClass::function;
MyClass instance;
instance.*function_ptr;
As stated in the C++ FAQ Lite, macros and typedefs would greatly increase readability when using member function pointers (because their syntax isn't common in code).
I wrote that stuff last hours, and added it to my collection of useful stuff. The most difficult thing is to cope with the factory function, if the types you want to create are not related in any way. I used a boost::variant for this. You have to give it a set of types you ever want to use. Then it will keep track what is the current "active" type in the variant. (boost::variant is a so-called discriminated union). The second problem is how you store your function pointers. The problem is that a pointer to a member of A can't be stored to a pointer to a member of B. Those types are incompatible. To solve this, i store the function pointers in an object that overloads its operator() and takes a boost::variant:
return_type operator()(variant<possible types...>)
Of course, all your types' functions have to have the same return type. Otherwise the whole game would only make little sense. Now the code:
#include <boost/variant.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/preprocessor/repetition.hpp>
#include <map>
#include <string>
#include <iostream>
// three totally unrelated classes
//
struct foo {
std::string one() {
return "I ";
}
};
struct bar {
std::string two() {
return "am ";
}
};
struct baz {
std::string three() const {
return "happy!";
}
};
// The following are the parameters you have to set
//
// return type
typedef std::string return_type;
// variant storing an object. It contains the list of possible types you
// can store.
typedef boost::variant< foo, bar, baz > variant_type;
// type used to call a function on the object currently active in
// the given variant
typedef boost::function<return_type (variant_type&)> variant_call_type;
// returned variant will know what type is stored. C++ got no reflection,
// so we have to have a function that returns the correct type based on
// compile time knowledge (here it's the template parameter)
template<typename Class>
variant_type factory() {
return Class();
}
namespace detail {
namespace fn = boost::function_types;
namespace mpl = boost::mpl;
// transforms T to a boost::bind
template<typename T>
struct build_caller {
// type of this pointer, pointer removed, possibly cv qualified.
typedef typename mpl::at_c<
fn::parameter_types< T, mpl::identity<mpl::_> >,
0>::type actual_type;
// type of boost::get we use
typedef actual_type& (*get_type)(variant_type&);
// prints _2 if n is 0
#define PLACEHOLDER_print(z, n, unused) BOOST_PP_CAT(_, BOOST_PP_ADD(n, 2))
#define GET_print(z, n, unused) \
template<typename U> \
static variant_call_type get( \
typename boost::enable_if_c<fn::function_arity<U>::value == \
BOOST_PP_INC(n), U>::type t \
) { \
/* (boost::get<actual_type>(some_variant).*t)(n1,...,nN) */ \
return boost::bind( \
t, boost::bind( \
(get_type)&boost::get<actual_type>, \
_1) BOOST_PP_ENUM_TRAILING(n, PLACEHOLDER_print, ~) \
); \
}
// generate functions for up to 8 parameters
BOOST_PP_REPEAT(9, GET_print, ~)
#undef GET_print
#undef PLACEHOLDER_print
};
}
// incoming type T is a member function type. we return a boost::bind object that
// will call boost::get on the variant passed and calls the member function
template<typename T>
variant_call_type make_caller(T t) {
return detail::build_caller<T>::template get<T>(t);
}
// actions stuff. maps an id to a class and method.
typedef std::map<std::string,
std::pair< std::string, std::string >
> actions_type;
// this map maps (class, method) => (factory, function pointer)
typedef variant_type (*factory_function)();
typedef std::map< std::pair<std::string, std::string>,
std::pair<factory_function, variant_call_type>
> class_method_map_type;
// this will be our test function. it's supplied with the actions map,
// and the factory map
std::string test(std::string const& id,
actions_type& actions, class_method_map_type& factory) {
// pair containing the class and method name to call
std::pair<std::string, std::string> const& class_method =
actions[id];
// real code should take the maps by const parameter and use
// the find function of std::map to lookup the values, and store
// results of factory lookups. we try to be as short as possible.
variant_type v(factory[class_method].first());
// execute the function associated, giving it the object created
return factory[class_method].second(v);
}
int main() {
// possible actions
actions_type actions;
actions["first"] = std::make_pair("foo", "one");
actions["second"] = std::make_pair("bar", "two");
actions["third"] = std::make_pair("baz", "three");
// connect the strings to the actual entities. This is the actual
// heart of everything.
class_method_map_type factory_map;
factory_map[actions["first"]] =
std::make_pair(&factory<foo>, make_caller(&foo::one));
factory_map[actions["second"]] =
std::make_pair(&factory<bar>, make_caller(&bar::two));
factory_map[actions["third"]] =
std::make_pair(&factory<baz>, make_caller(&baz::three));
// outputs "I am happy!"
std::cout << test("first", actions, factory_map)
<< test("second", actions, factory_map)
<< test("third", actions, factory_map) << std::endl;
}
It uses pretty fun techniques from boost preprocessor, function types and bind library. Might loop complicated, but if you get the keys in that code, it's not much to grasp anymore. If you want to change the parameter count, you just have to tweak variant_call_type:
typedef boost::function<return_type (variant_type&, int)> variant_call_type;
Now you can call member functions that take an int. Here is how the call side would look:
return factory[class_method].second(v, 42);
Have fun!
If you now say the above is too complicated, i have to agree with you. It is complicated because C++ is not really made for such dynamic use. If you can have your methods grouped and implemented in each object you want create, you can use pure virtual functions. Alternatively, you could throw some exception (like std::runtime_error) in the default implementation, so derived classes do not need to implement everything:
struct my_object {
typedef std::string return_type;
virtual ~my_object() { }
virtual std::string one() { not_implemented(); }
virtual std::string two() { not_implemented(); }
private:
void not_implemented() { throw std::runtime_error("not implemented"); }
};
For creating objects, a usual factory will do
struct object_factory {
boost::shared_ptr<my_object> create_instance(std::string const& name) {
// ...
}
};
The map could be composed by a map mapping IDs to a pair of class and function name (the same like above), and a map mapping that to a boost::function:
typedef boost::function<my_object::return_type(my_object&)> function_type;
typedef std::map< std::pair<std::string, std::string>, function_type>
class_method_map_type;
class_method_map[actions["first"]] = &my_object::one;
class_method_map[actions["second"]] = &my_object::two;
Calling the function would work like this:
boost::shared_ptr<my_object> p(get_factory().
create_instance(actions["first"].first));
std::cout << class_method_map[actions["first"]](*p);
Of course, with this approach, you loose flexibility and (possibly, haven't profiled) efficiency, but you greatly simplify your design.
I think the most important thing to find out here is, do all of your methods have the same signature? If they do, this is a trivial use of boost bind(if you're into that), functors are an option(the static, duck type kind), or just plain ole virtual inheritance is an option. Inheritance isnt currently in vogue but its pretty easy to understand and I dont think it complicates things anymore then using boost bind(imho best for small non systemic functors).
here is a sample implementation
#include<iostream>
#include<map>
#include<string>
using std::map;
using std::string;
using std::cout;
using std::pair;
class MVCHandler
{
public:
virtual void operator()(const string& somekindofrequestinfo) = 0;
};
class MyMVCHandler : public MVCHandler
{
public:
virtual void operator()(const string& somekindofrequestinfo)
{
cout<<somekindofrequestinfo;
}
};
void main()
{
MyMVCHandler myhandler;
map<string, MVCHandler*> handlerMap;
handlerMap.insert(pair<string, MVCHandler*>("mysuperhandler", &myhandler));
(*handlerMap["mysuperhandler"])("somekindofrequestdata");
}
Like many C++ questions, this looks like another application of Boost. You basically want to store the result of boost::bind(&Class::member, &Object). [edit] Storing such a result is easy with boost::function.
You can try using factory or abstract factory design patterns for the class, and a function pointer for the function.
I found the following 2 web pages with implementations when I was searching for solutions for a similar problem:
Factory
Abstract factory
If you do not want to use member function pointers, you can use statics which take an argument of the class instance. For example:
class MyClass
{
public:
void function();
static void call_function(MyClass *instance); // Or you can use a reference here.
};
MyClass instance;
MyClass::call_function(&instance);
This requires more work on the coder and causes maintainability issues (since if you update the signature of one, you must update that of the other as well).
You could also use a single static function which calls all your member functions:
class MyClass
{
public:
enum Method
{
fp_function,
};
void function();
static void invoke_method(MyClass *instance, Method method); // Or you can use a reference here.
};
void MyClass::invoke_method(MyClass *instance, Method method)
{
switch(method)
{
default:
// Error or something here.
return;
case fp_function:
instance->function();
break;
// Or, if you have a lot of methods:
#define METHOD_CASE(x) case fp_##x: instance->x(); break;
METHOD_CASE(function);
#undef METHOD_CASE
}
// Free logging! =D
}
MyClass instance;
MyClass::invoke_method(instance, MyClass::fp_function);
You can also use dynamic loading of the functions:
Use GetProcAddress in Windows, and dlsym in Unix.
Go for Subject-Observer design pattern.