是否可以对可变参数模板进行多次特化,其中一个模板参数是静态绑定的成员函数指针?
我正在尝试构建一个委托,其中回调函数是一个编译时常量 - 从而帮助优化器查看函数指针边界。
我有以下代码,我将成员函数指针作为模板参数传递,并且由于函数指针是一个在编译时已知的常量,我的期望是优化器将能够通过该函数指针边界。
我创建了2个委托,delegate0和delegate1,它们分别用于具有0和1参数的成员函数。
#include <iostream>
template<class class_t, void (class_t::*mem_func_t)()>
struct delegate0
{
delegate0( class_t *obj_ )
: _obj(obj_)
{ }
void operator()()
{
(_obj->*mem_func_t)();
}
private:
class_t *_obj;
};
template<class class_t, typename arg0, void (class_t::*mem_func_t)(arg0)>
struct delegate1
{
delegate1( class_t *obj_, arg0 a0_ )
: _obj(obj_)
, _a0(a0_)
{ }
void operator()()
{
(_obj->*mem_func_t)(_a0);
}
private:
class_t *_obj;
arg0 _a0;
};
struct app
{
void cb()
{
std::cout << "hello world\n";
}
void cb1(int i)
{
std::cout << "hello world " << i << "\n";
}
};
int main()
{
app* foo = new app;
delegate0<app, &app::cb> f(foo);
f();
delegate1<app, int, &app::cb1> f1(foo, 5);
f1();
}
但是,我想以两种方式对此进行改进:
delegate<&app::cb>
(当cb不含糊不清),class_t,mem_func_t,arg0,arg1等等时,都是从app::cb
的签名中推断出来的。 我意识到成员函数指针不是一个类型,但就像你可以传递一个特定的整数作为模板参数(元编程中使用的ala模板递归),我想你可以有一个特定的成员函数指针作为参数 - 从而允许静态绑定到该函数。
我追求甚至可能吗? 如果不是,可以是1或2中的任何一个吗? 我真的很感激一个有效的例子,因为我一直在用我的键盘撞击我的键盘而没有成功。
我有以下悲惨的尝试。这显然不是我想要的,但为了显示我前进的方向,我认为包括它可能是有用的。
template<typename...>
struct delegate;
template<class class_t, void (class_t::*mem_func_t)()>
struct delegate<class_t, decltype(mem_func_t)>
{
delegate( class_t *obj_ )
: _obj(obj_)
{ }
void operator()(mem_func_t f)
{
(_obj->*f)();
}
class_t *_obj;
};
template<class class_t, typename arg0, void (class_t::*mem_func_t)(arg0)>
struct delegate<class_t, arg0, decltype(mem_func_t)>
{
delegate( class_t *obj_, arg0 a0_ )
: _obj(obj_)
, _a0(a0_)
{ }
void operator()()
{
(_obj->*mem_func_t)(_a0);
}
class_t *_obj;
arg0 _a0;
};
答案 0 :(得分:1)
声明采用任何类型的模板:
template <typename T, T value>
struct Delegate;
然后将其专门用于成员函数对象(为每个cv-qualifier做4次):
template <typename R, typename C, typename... A, R (C::* value)(A...) const>
struct Delegate<R(C::*)(A...) const, value>
{
// do whatever you like with R, C, A... .
};
如前所述,您需要decltype
:
Delegate<decltype(&SomeClass::method), &SomeClass::method> del;
或者,您可以使用my function_traits
class直接从T中提取R,C和A ...因此您不需要专门化,但是decltype
仍然需要重复该方法。