【发布时间】:2020-09-22 11:43:22
【问题描述】:
我有两个函数需要由类公开,它们看起来像这样(后面会更多):
void print_a(std::string s);
void print_b(std::string s, int val);
“在幕后”他们在做同样的事情,即在地图中查找并将调用参数传递给地图检索到的函数指针:
#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);
}
}
};
我不喜欢涉及大量样板代码的事实。我想知道是否可以将成员传递到模板中以便我可以这样做:
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;
};
感谢任何关于如何摆脱样板的想法。
【问题讨论】:
-
您确定要将
print_a定义为decltype(print_x<a_table>)的类型,而不是使用print_x的函数吗? -
我不太确定我是否理解您的用例 - 函数是如何在地图/表格中注册的?是否只有为该类型注册的两个成员函数?
-
基本上我在每张地图中有 6 个功能。所以 6 x
do_stuff_a和 6xdo_stuff_b。我省略了地图的人口以提供一个尽可能简短的例子。 -
而且都是成员函数?
-
是的,他们必须是。