在使用std::bind的时候,我们经常会遇到这么个提示:
error: decltype evaluates to ‘MyFunction&’, which is not a class or enumeration type
对应的代码如下
using HtmlTemplateFunction = std::function<int(std::vector<int>)>;
class MyFunction {
public:
MyFunction() {
//regist(std::bind(&decltype(getClass(this))::doSum,this,std::placeholders::_1));
regist(std::bind(&(decltype(*this)::doSum,this,std::placeholders::_1)));
}
void regist(HtmlTemplateFunction f) {
func = f;
}
void doInvoke() {
std::vector<int> v;
v.push_back(1);
v.push_back(2);
int ret = func(v);
std::cout<<"ret is "<<ret<<std::endl;
}
int doSum(std::vector<int> p) {
auto v1 = p[0];
auto v2 = p[1];
return v1+v2;
}
private:
HtmlTemplateFunction func;
};
虽然C++提供了decltype的接口可以获取指针类型。但是仍然会提示非static函数。所以我们需要找一个方法来获取这个指针的类型。最简单的方法就是使用模板来实现。方法如下:
template <typename T>
T getClass(T *) {
//Trigger(MethodNotSupportException,"cannot use this function");
}
这个函数其实没有任何实现,但是最关键的作用就是将一个指针的类型解析出来了。使用方法如下:
MyFunction()
{
regist(std::bind(&decltype(getClass(this))::doSum,this,std::placeholders::_1));
}
加上getClass之后就能正常获取class类型了。哈哈。这个方法在Obotcha的反射和Gagira的路由表注入中都使用了该方法:
#define Inject(method,url,instance,function) \
{\
auto func = std::bind(&decltype(getClass(instance))::function,instance.get_pointer());\
ControllerRouter r = createControllerRouter(func,instance); \
HttpRouter router = createHttpRouter(url,r);\
st(HttpRouterManager)::getInstance()->addRouter(method,router);\
}\
大家要是对Obotcha感兴趣的话,可以看一下Obotcha的gitee/github:
Obotcha: Tool Library by C++14
GitHub - wangsun1983/Obotcha: Tool library writen by C++14
谢谢。