Можно ли иметь несколько специализаций вариационного шаблона, где один из параметров шаблона является статически связанным указателем на функцию-член?
Я пытаюсь создать делегат, в котором функция обратного вызова является временем компиляции.константа - тем самым помогает оптимизатору видеть за границей указателя функции.
У меня есть следующий код, в котором я передаю указатель на функцию-член в качестве параметра шаблона, и поскольку указатель на функцию является константой, известной при компиляции- время, я ожидаю, что оптимизатор сможет работать через границу указателя функции.
Я создал 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
.
Я понимаю, чтоУказатель на функцию-член не является типом, но точно так же, как вы можете передать конкретное целое число в качестве параметра шаблона (например, рекурсию шаблона, используемую в метапрограммировании), я полагаю, вы можете иметь конкретный указатель на функцию-член в качестве параметра - тем самым позволяя статическую привязкуфункция.
То, что я после даже возможно?Если нет, возможно ли 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;
};