I am implementing a hashtable, and I have written the following (fragment of a) class definition:
template <typename KEY, typename VAL>
class ExtendibleHashTable {
/* Main hash function used. Initially, the identity function. */
size_t hash(KEY key) {
return key;
}
I want to further add a public method, that allows one to set a custom hash function. I do know about function pointers, so I tried something like this (underneath, in the same class definition):
/* Set new hash. */
void set_hash(size_t new_hash(KEY)) {
this -> hash = new_hash;
}
However, this does not compile.
Can you tell me the best way to achieve this effect? I have looked at the <functional> header but it doesn't seem to be the answer I need (or maybe I haven't understood its purpose).
You cannot replace member functions dynamically in C++. Nor can you dynamically add member functions.
You can, however, have a class that contains function pointers or std:: function objects that you can change at run-time. So, you could for example do something like this:
class ExtendibleHashTable {
private:
std::function<size_t (KEY)> m_hash_func;
public:
size_t hash(KEY key) {
if (m_hash_func) {
return m_hash_func(key);
}
return key;
}
void set_hash(const std::function<size_t (KEY)>& func) {
m_hash_func = func;
}
};
In the above, the hash function will by default just return key if no specific function has been set. But, if set_hash has been called with an appropriate hash function (free standing function, function object or lambda), then it will instead call that function and return its result.
Related
I have a set of hardware handler classes, all derived from a base class, which have to respond to an incoming data packet. Part of this packet is an ASCII string, which determined which member function of the hardware handler is used to process the packet (for example "fan" would execute the ToggleFan() function.
class HardwareHandler {
virtual void dispatchCommand(const String& cmd) = 0;
}
class FooblerHandler : public HardwareHandler {
void toogleFan();
void dispatchCommand(const String& cmd) {
//is this a "good" way to do this?
if (cmd == "fan")
toggleFan();
}
}
I am using JUCE as a framework, which means I have things like templated HashMaps and String.
However, I'm having trouble coming up with a tidy way of selecting the right handler function based on this string. The construct
if (str == "hello")
FooCommand();
else if (str == "bar")
BarCommand();
looks pretty ugly to me conceptually as there are a lot of relatively expensive string comparisons in there. However, the code is easy to write and the logic is kept in a single place per class.
Another alternative I have tried is to make a hash-map of the strings to an enum and use that a the switch statement:
switch (str.getHash())
{
case CmdFoo:
FooCommnad();
break;
....and so on
}
However this also requires me to set up a static hash-map, as well as maintain the switch to match.
Something else I tried is a hash-map form the string to the member function pointer itself, hoping to be able to jump directly from the string to the member function without having list them in a case statement, and also allows a very generic dispatch function, as it just needs to look up in the hash-map, it doesn't even need to know all the options - they can be contained solely in the hash-map, allowing me to maybe push the dispatch function into the base handler class and not repeat myself in each specific device handler. However, this method has stumped me as I can't quite work out how to do it correctly, or even if it is possible to do this with a static hash-map and member-functions.
Is there an idiomatic way to dispatch to member functions based on a string (or similar hard-to-compare type), preferably with as much logic able to be genericised and moved to the parent class as possible?
Here is my try. You can encapsulate the mapping mechanism into a class:
#include <iostream>
#include <string>
#include <functional>
#include <map>
class X;
template<class X>
class handler_factory;
template<>
class handler_factory<X>
{
private:
using HandlerType = void (X::*)();
public:
handler_factory();
HandlerType get(const std::string& name) const
{
if (handlers.find(name) == handlers.end())
return nullptr;
else
return (*handlers.find(name)).second;
}
private:
std::map<std::string, HandlerType> handlers;
};
class X
{
public:
friend class handler_factory<X>;
private:
void f();
void h();
};
handler_factory<X>::handler_factory()
{
handlers["f"] = &X::f;
handlers["h"] = &X::h;
}
void X::f() { std::cout << "X::f();"; }
void X::h() { std::cout << "X::h();"; }
And your dispatch method can be implemented as:
void dispatch_method(const std::string& name)
{
if (find_handler(name))
(this->*find_handler(name))();
}
int main()
{
X().dispatch_method("f");
}
Where find_handler is defined as a private helper method:
private:
auto find_handler(const std::string& name)
-> decltype(handler_factory<X>().get(name))
{
return handler_factory<X>().get(name);
}
I think the most efficient way to deal with the problem is creating a std::map that would map your strings into appropriate functions. The method is fast (due to the logarithmic searching algorithm), easy and safe.
class FooblerHandler : public HardwareHandler {
typedef void (HardwareHandler::*function)();
map<string,function> commandMap;
void dispatchCommand(const string& cmd) {
if(commandMap.count(cmd))
(this->*commandMap.find(cmd)->second)();
else
cout << "No command found with name \"" <<cmd<< "\"." << endl;
}
};
And of course you should init the map inside the constructor (or somewhere before using it):
commandMap["fan"] = &FooblerHandler::toogleFan;
commandMap["someOtherCommand"] = &FooblerHandler::otherFunction;
Maps and included in the Standard Template Library (STL) which nearly all IDE's supply.
EDIT:
I didn't quite read the text at the end. Well - now you know the syntax :)
Let's say I have a family of classes which all implement the same interface, perhaps for scheduling:
class Foo : public IScheduler {
public:
Foo (Descriptor d) : IScheduler (d) {}
/* methods */
};
class Bar : public IScheduler {
public:
Bar (Descriptor d) : IScheduler (d) {}
/* methods */
};
Now let's say I have a Scheduler class, which you can ask for an IScheduler-derived class to be started for a given descriptor. If it already exists, you'll be given a reference to it. If one doesn't exist, then it creates a new one.
One hypothetical invocation would be something like:
Foo & foo = scheduler->findOrCreate<Foo>(descriptor);
Implementing that would require a map whose keys were (descriptor, RTTI) mapped to base class pointers. Then you'd have to dynamic_cast. Something along these lines, I guess:
template<class ItemType>
ItemType & Scheduler::findOrCreate(Descriptor d)
{
auto it = _map.find(SchedulerKey (d, typeid(ItemType)));
if (it == _map.end()) {
ItemType * newItem = new ItemType (d);
_map[SchedulerKey (d, typeid(ItemType))] = newItem;
return *newItem;
}
ItemType * existingItem = dynamic_cast<ItemType>(it->second);
assert(existingItem != nullptr);
return *existingItem;
}
Wondering if anyone has a way to achieve a similar result without leaning on RTTI like this. Perhaps a way that each scheduled item type could have its own map instance? A design pattern, or... ?
The address of a function, or class static member, is guaranteed to be unique (as far as < can see), so you could use such an address as key.
template <typename T>
struct Id { static void Addressed(); };
template <typename ItemType>
ItemType const& Scheduler::Get(Descriptor d) {
using Identifier = std::pair<Descriptor, void(*)()>;
Identifier const key = std::make_pair(d, &Id<ItemType>::Addressed);
IScheduler*& s = _map[key];
if (s == nullptr) { s = new ItemType{d}; }
return static_cast<ItemType&>(*s);
}
Note the use of operator[] to avoid a double look-up and simplify the function body.
Here's one way.
Add a pure virtual method to IScheduler:
virtual const char *getId() const =0;
Then put every subclass to it's own .h or .cpp file, and define the function:
virtual const char *getId() const { return __FILE__; }
Additionally, for use from templates where you do have the exact type at compile time, in the same file define static method you can use without having class instance (AKA static polymorphism):
static const char *staticId() { return __FILE__; }
Then use this as cache map key. __FILE__ is in the C++ standard, so this is portable too.
Important note: use proper string compare instead of just comparing pointers. Perhaps return std::string instead of char* to avoid accidents. On the plus side, you can then compare with any string values, save them to file etc, you don't have to use only values returned by these methods.
If you want to compare pointers (like for efficiency), you need a bit more code to ensure you have exactly one pointer value per class (add private static member variable declaration in .h and definition+initialization with FILE in corresponding .cpp, and then return that), and only use the values returned by these methods.
Note about class hierarchy, if you have something like
A inherits IScheduler, must override getId()
A2 inherits A, compiler does not complain about forgetting getId()
Then if you want to make sure you don't accidentally forget to override getId(), you should instead have
abstract Abase inherits IScheduler, without defining getId()
final A inherits Abase, and must add getId()
final A2 inherits Abase, and must add getId(), in addition to changes to A
(Note: final keyword identifier with special meaning is C++11 feature, for earlier versions just leave it out...)
If Scheduler is a singleton this would work.
template<typename T>
T& Scheduler::findOrCreate(Descriptor d) {
static map<Descriptor, unique_ptr<T>> m;
auto& p = m[d];
if (!p) p = make_unique<T>(d);
return *p;
}
If Scheduler is not a singleton you could have a central registry using the same technique but mapping a Scheduler* / Descriptor pair to the unique_ptr.
If you know all your different subtypes of IsScheduler, then yes absolutely. Check out Boost.Fusion, it let's you create a map whose key is really a type. Thus for your example, we might do something like:
typedef boost::fusion::map<
boost::fusion::pair<Foo, std::map<Descriptor, Foo*>>,
boost::fusion::pair<Bar, std::map<Descriptor, Bar*>>,
....
> FullMap;
FullMap map_;
And we will use that map thuslly:
template <class ItemType>
ItemType& Scheduler::findOrCreate(Descriptor d)
{
// first, we get the map based on ItemType
std::map<Descriptor, ItemType*>& itemMap = boost::fusion::at_key<ItemType>(map_);
// then, we look it up in there as normal
ItemType*& item = itemMap[d];
if (!item) item = new ItemType(d);
return item;
}
If you try to findOrCreate an item that you didn't define in your FullMap, then at_key will fail to compile. So if you need something truly dynamic where you can ad hoc add new schedulers, this won't work. But if that's not a requirement, this works great.
static_cast the ItemType* to void* and store that in the map.
Then, in findOrCreate, just get the void* and static_cast it back to ItemType*.
static_casting T* -> void* -> T* is guaranteed to get you back the original pointer. You already use typeid(ItemType) as part of your key, so it's guaranteed that the lookup will only succeed if the exact same type is requested. So that should be safe.
If you also need the IScheduler* in the scheduler map just store both pointers.
I am looking for a way to call different functions by a string input.
I have a map that ties each unique string to a function pointer and a lookup function to search the map and return a pointer if found.
Now the trick is, I need a way to store and return pointers to functions with at least different return types, if possible, also with different signatures.
The usage would be:
Get a string input from a network socket ->
find and execute the found function -> shove the result straight back into the socket to be serialized and sent, not caring what actually happened.
Is this doable? If not, how would one approach this task?
That can be done with a bit of boilerplate code in different ways. If the number of signatures is small enough you can hold multiple vectors of function pointers (one per function type) and then a map that maps the function name with a type identifier (used to select the vector) and the position within the vector.
The second option would be to store a boost::variant (again, if the set of signatures is small). You would need to provide a visitor object that evaluates the function (for each function type stored) and yields the result. The type is managed by the boost::variant type so there would be no need for the type tag to be stored in the map.
You can also use full type erasure and store in the map a tag determining the type of function to be called and a boost::any object storing the function pointer. You can use the type information to retrieve the pointer and execute the function, but you will have to manually handle the switch based on function type.
The simplest approach, on the other hand, is to write adapters that have a fixed interface. Then just store the pointers to the adapters in the map.
While you can't store different function pointers, you can store objects which contain those functions.
#include <iostream>
#include <cmath>
#include <map>
#include <string>
using namespace std;
class Functor{
public:
template<class T>
void operator()(T data){}
};
template<class T>
class BaseFunctor : public Functor{
public:
virtual void CallFunction(T data){ }
};
class FunctionPointer1 : public BaseFunctor<void *>{
public:
void doFunction1(){
cout << "Do Function 1"<<endl;
}
template<class T>
void CallFunction(T data){ doFunction1(); }
template<class T>
void operator()(T data){ this->CallFunction(data); }
};
class FunctionPointer2 : public BaseFunctor<int>{
public:
void doFunction2(int variable){ cout << "Do function 2 with integer variable" << variable <<endl; }
template<class T>
void CallFunction(T data) { doFunction2(data);}
template<class T>
void operator()(T data){ this->CallFunction(data); }
};
class FunctionPerformer{
private:
map<string,Functor> functions;
public:
FunctionPerformer(){
//init your map.
FunctionPointer1 function1;
FunctionPointer2 function2;
//-- follows
functions["Function1"] = function1;
functions["Functions2"] = function2;
//-- follows
}
Functor getFunctionFromString(string str){
return functions[str]
}
};
int main(int argc, char *argv[])
{
map<string,Functor> functions;
FunctionPerformer performer;
Functor func1, func2; // to hold return values from perfomer()
FunctionPointer1 *fn1; // to casting and execute the functions
FunctionPointer2 *fn2; // to casting and execute the functions
func1 = performer.getFunctionFromString("Function1");//get data
func2 = performer.getFunctionFromString("Function2");
//following two lines to cast the object and run the methods
fn1 = reinterpret_cast<FunctionPointer1 *>(&func1);
(*fn1)(NULL);
//following two lines to cast the object and run the methods
fn2 = reinterpret_cast<FunctionPointer2 *>(&func2);
(*fn2)(10);
system("Pause");
return 0;
}
I think the edited part makes it clearer?
This code can be optimized a little. Play around with it.
This is doable in C++11 with Variadic Templates. Check my answer at https://stackoverflow.com/a/33837343/1496826
No, it's really not doable, you need a real interpreted language if you want to do something like this. As soon as the signature is not constant then you need something a lot more involved.
How about making all those functions have the same signature? You could make all return types implement an interface, or use a collection, class, union or struct. Same for the arguments.
Can't you use specialization and templates to work around the issue?
template <class T>
T FooBar(void * params);
template<> int FooBar<int>( void * params );
template<> char FooBar<char>( void * params );
Instead of storing the function pointers themselves, which are too different from one another to be accommodated into the same data structure, you can store adaptors that take care of bridging the mismatch. This is a form of type-erasure. An example:
// Imaginary important resources
blaz_type get_blaz();
qux_type get_qux();
// The functions we'd like to put in our map
int foo(blaz_type);
std::string bar(qux_type);
using context_type = std::tuple<blaz_type, qux_type>;
using callback_type = std::function<void(context_type, socket_type&)>;
using std::get;
std::map<std::string, callback_type> callbacks = {
{
"foo"
, [](context_type context, socket_type& out)
{ marshall(out, foo(get<0>(std::move(context)))); }
}
, {
"bar"
, [](context_type context, socket_type& out)
{ marshall(out, bar(get<1>(std::move(context)))); }
}
};
In this example the adaptors are not stateful so you can actually use void (*)(context_type, socket_type&) as the callback_type.
Do note that this kind of design is a bit brittle in that the context_type needs to know about every kind of parameter a stored callback might ever need. If at some later point you need to store a callback which needs a new kind of parameter, you need to modify context_type -- if you improve the above design not to use magic numbers like 0 and 1 as parameters to std::get you could save yourself some pains (especially in the reverse situation of removing types from context_type). This is not an issue if all callbacks take the same parameters, in which case you can dispense yourself with the context_type altogether and pass those parameters to the callbacks directly.
Demonstration on LWS.
I have a very simple class definition as follows:
#include "../bshttp/controllers.h"
#include <iostream>
#include <string>
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this)
{
m_urlRules["print"] = REG_NAME &DerivedController::print;
//regController(REG_NAME &DerivedController::print,"print");
regController(REG_NAME &DerivedController::printView,"printView");
}
void * print()
{
return NULL;
}
void * printView()
{
cout<<"Print view!"<<endl;
return NULL;
}
};
where either
m_urlRules["print"] = REG_NAME &DerivedController::print;
or
regController(REG_NAME &DerivedController::printView,"printView");
has to be called for all of the member functions. What it does it that it takes the member function pointer of the class and maps with a string, so later on the function can be identified with a string.
Everything is all well and working, but when the class structure gets bigger, the programmer will have to repetitively call this function for every single member function. Is there anyway to use the preprocessor, or any preprocessing library such as the boost-wave, so that the programmer doesn't have to do these repetitive calling?
EDIT:
Sorry for the confusion, I clearly did not describe the problem well enough here.
I am mapping strings to member function pointer;
m_urlRules is a std::map with string as the key, and member function pointer as value
regController is basically a setter function for m_urlRules, so both statements effectively does the same thing, which maps a string to a member function.
REG_NAME is a macro to replace a very ugly typecast.
what I am trying to do is that, if the class where to have the following structure,
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this);
void * print();
void * print2();
void * print3();
void * print4();
};
I dont have to do the following in the constructor:
m_urlRules["print"] = REG_NAME &DerivedController::print;
m_urlRules["print1"] = REG_NAME &DerivedController::print1;
m_urlRules["print2"] = REG_NAME &DerivedController::print2;
m_urlRules["print3"] = REG_NAME &DerivedController::print3;
m_urlRules["print4"] = REG_NAME &DerivedController::print4;
Well, you're trying to build the runtime type information (RTTI) on your own, so no there is no preprocessor macro for this. Mainly because preprocessor macros expand to a single place, and the place where you declare, and the place, where you register your functions are different.
Qt and qmake, does something like this, it finds the functions marked signals/slots, and builds a moc object for RTTI. That's about the best you can get with c++. Other languages like java, and delphi, has more RTTI, than c++, and makes it possible to query functions at runtime.
I am not exactly sure I understood completely your problem, but why don't use the built-in data structure, such as map, in which you can map it to a key (your string).
Here some examples
I would first work on removing the ugly typecast (even in macro form). This can be done by moving the m_urlRules out of BS_Controllers and into an intermediate (or proxy) template class. The template is used to resolve the map to the right derived type. (I didn't know how you defined BS_Controllers, so I made one up.)
class BS_Controllers {
protected:
virtual ~BS_Controllers () {}
public:
virtual void * invokeRule (const std::string &) = 0;
};
template <typename D>
class BS_Proxy : public BS_Controllers {
typedef std::map<std::string, void *(D::*)()> UrlRuleMap;
static UrlRuleMap & urlRules () {
static UrlRuleMap urlRules_;
return urlRules_;
}
void * invokeRule (const std::string &s) {
typename UrlRuleMap::iterator i = urlRules().find(s);
if (i == urlRules().end()) return 0;
return (dynamic_cast<D *>(this)->*(i->second))();
}
protected:
static void regController (void *(D::*m)(), const std::string &s) {
urlRules()[s] = m;
}
};
Now, the DerivedController can be initialized fairly easily, by invoking the regController method of the proxy class.
#define REG_RULE(D, x) BS_Proxy<D>::regController(&D::x, #x)
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
REG_RULE(DerivedController, print);
REG_RULE(DerivedController, printView);
}
};
public:
DerivedController() {
static Populate populate_;
}
void * print() { return NULL; }
void * printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
};
You can view a demo of the above code.
If you want to make the population semi-automatic, you still have to define the list of methods somewhere. You could list them out in a file.
// DerivedController rules
DERIVED_RULE_INC(print)
DERIVED_RULE_INC(printView)
//...
And then change your DerivedController class to use this file:
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
#define DERIVED_RULE_INC(x) REG_RULE(DerivedController, x);
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
}
};
public:
DerivedController() {
static Populate populate_;
}
#define DERIVED_RULE_INC(x) void * x ();
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
};
void * DerivedController::print() { return NULL; }
void * DerivedController::printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
Now, if you add another rule to the file, the registration code and the method declaration is automatic. But the definition of the method needs to be implemented, or a linker error will be generated about the missing method definition.
I believe you want to use this feature for logging reasons, to see where problems appear.
I think you're searching for something like:
urlRules ("<function name>");
regController("<function name>");
Instead of
m_urlRules["<function name>"] = REG_NAME &DerivedController::print;
regController(REG_NAME &DerivedController::printView,"<function name>");
You can define such makros like so:
#define urlRules(x) { m_urlRules[(x)] = REG_NAME &DerivedController::print; }
#define regController(x) { regController(REG_NAME &DerivedController::printView,(x)); }
Attention: I have not tested it, it might not work but in my understanding it should.
EDIT:
Ah now I understand, you want calls for every function within the constructor.
Actually, the constructor is the wrong place, because it gets called for every object you create, but you only have to assign this pointers once. (on startup for example)
See, the functions of a class only exist once in memory, and the thing that is connected to the pointer is the yield data, so all member variables.
There is no simple way to get all class members by name and then run over them, sorry.
At least not as I know of.
But you should keep in mind that the function pointers won't change for any given object.
An external function which does the work would be more intelligent. Called on startup.
My goal is to access a class that is passed in as a parameter inside of myFunction.
Here's what I'm trying to do:
void myFunction(string myString)
{
callFunctionOn(OuterType::InnerType::myString);
}
I'm trying to call some function on something that's in a type. For example, my code in some other file might look like:
namespace OuterType {
namespace InnerType {
//stuff here
}
}
However, using myString in that way doesn't work. If myString holds the value "class1", then I want that callFunctionOn part to be interpreted as
callFunctionOn(OuterType::InnerType::class1);
I feel like this is super simple, but I've been programming all day and my mind grows tired...
SOLVED: It looks like in order to this in this way, I'd need a language with reflection. To solve this I took a different approach to the problem and passed in a pointer to the class instead.
C++ doesn't have reflection built in, but it does have pointers to data, functions, and class members. So you can use a std::map or unordered_set to find the pointer with a particular name (you have to add all the name/pointer pairs into the map beforehand).
Your solution is likely to look something like:
namespace Outer
{
namespace Inner
{
void funcA( void ) { std::cout << "called funcA" << std::endl; }
std::map< std::string, void (*)(void) > members;
}
}
// in some initialization function
Outer::Inner::members["funcA"] = &Outer::Inner::funcA;
// later
std::string myString = "funcA";
void (*f)(void) = Outer::Inner::members[myString]; // lookup function by name
(*f)(); // call function via its pointer
Of course the type of the pointer will probably need to change to meet your application requirements.
You're trying to access a variable based on a run-time string that contains its name? That's not possible; the names of variables disappear after compilation and linking. (Except insofar as they are kept around to facilitate debugging).
Do you mean :
OuterType::InnerType::callFunctionOn(myString);
maybe this idea: operator() can take parameters, wrapping it in a class ine can make calls that are resolved in the overloaded operator() based on its parameters.
template<typename TypeSig, class InstanceOf, typename NA,typename Args>
class FuncMap {
public:
typedef TypeSig (InstanceOf:: *cbMethod) ( NA, Args );
FuncMap( InstanceOf & cInst, cbMethod cbM ) : mcInst(cInst) {mcbM = cbM;}
TypeSig operator() ( NA na, Args args) {return (mcInst.*mcbM)(na, args);}
private:
InstanceOf & mcInst;
cbMethod mcbM;
};
you need to build a map of runtime string values as keys and pointers to instance methods as seen above. i used this for re-dispatch tracing and custom runtime dispatch with lesser than RTTI overhead.
this allows you to have default, if no key found, or other logic as you wish.