I have two functions which need to be exposed by the class and they look like this (more will follow):
void print_a(std::string s);
void print_b(std::string s, int val);
"Under the hood" they are doing the same exact thing namely doing a lookup in a map and passing the call parameters to the function pointer retrieved by the map:
#include <stdint.h>
#include <iostream>
#include <string>
#include <map>
class Thing{
private:
void do_a(){
std::cout << "hello";
}
//there might be also a method do_a_extended() which has a different key in the map
void do_b(int age){
std::cout << "my age is " << age;
}
typedef void (Thing::*do_stuff_a)();
typedef void (Thing::*do_stuff_b)(int);
std::map<std::string, do_stuff_a> a_table;
std::map<std::string, do_stuff_b> b_table;
public:
void print_a(std::string s){
do_stuff_a handler = a_table[s];
if(handler){
(this->*handler)();
}
}
void print_b(std::string s, int val){
do_stuff_b handler = b_table[s];
if(handler){
(this->*handler)(val);
}
}
};
I dislike the fact that there is a lot of boilerplate code involved. I wonder if its possible to pass a member into template so I can this:
class Thing{
private:
void do_a(){
std::cout << "hello";
}
void do_b(int age){
std::cout << "my age is " << age;
}
typedef void (Thing::*do_stuff_a)();
typedef void (Thing::*do_stuff_b)(int);
std::map<std::string, do_stuff_a> a_table;
std::map<std::string, do_stuff_b> b_table;
template<<MAP_MEMBER>,typename ... PP>
void print_x(std::string s, PP &&... pp){
auto handler = <MAP_MEMBER>[s];
if(handler){
(this->*handler)(std::forward<PP>(pp) ...);
}
}
public:
typedef decltype(print_x<a_table>) print_a;
typedef decltype(print_x<b_table>) print_b;
};
Any ideas on how to get rid of boilerplate is appreciated.
Aucun commentaire:
Enregistrer un commentaire