Помощник для перегруженного указателя на функцию-член
Я хочу иметь "более приятную" операцию приведения к указателю на метод.
Дан класс с перегруженными функциями-членами и шаблоном, который ест все виды указателей и объектов-членов и просто вызывает их.
class A
{
public:
void Do( int i ) { std::cout << "Hallo with int " << i << std::endl;}
void Do( float f ) { std::cout << "and with float " << f << std::endl;}
void Do( std::string s ) { std::cout << "also with string " << s << std::endl;}
};
template <typename OBJECT, typename METHOD, typename ... PARMS>
void Call( OBJECT& obj, METHOD m, PARMS ... parms)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
(obj.*m)(parms...);
}
Теперь, если я хочу использовать Call
шаблон, я должен вручную привести указатель, чтобы получить правильную версию перегруженных функций, таких как:
Call( a, static_cast< void(A::*)(int)>( &A::Do ), 1);
Call( a, static_cast< void(A::*)(float)>( &A::Do ), 8.88);
Call( a, static_cast< void(A::*)(std::string)>( &A::Do ), "Willi");
Поэтому я хотел бы сделать приведение более легким для чтения и получил этот вспомогательный класс:
template <typename > class Cast;
template < typename RET, typename ... ARGS >
class Cast< RET(ARGS...)>
{
public:
template < typename OBJ >
static auto From( RET(OBJ::*ptr)(ARGS...))-> RET(OBJ::*)(ARGS...)
{
return ptr;
}
};
и может использовать его как:
Call( a, Cast<void(int)>::From( &A::Do ), 100);
Call( a, Cast<void(float)>::From( &A::Do ), 4.46);
Call( a, Cast<void(std::string)>::From( &A::Do ),"Check it");
Q: Возможно ли сделать мой класс Cast
функция шаблона, чтобы получить синтаксис для вызова приведения немного проще? Я хочу что-то, что можно назвать так:
Call( a, Cast<void(std::string)>( &A::Do ), "Yeeeaaa!");
Но я не могу найти способ написать шаблонную функцию таким образом, потому что любая специализация, которую я написал, не была разрешена.
Разрешен любой вид с ++. Если C++17 дает новый путь, дайте мне знать!
Почему я не могу использовать параметры лямбды внутри функции вызова:
Мой реальный код должен только регистрировать указатели, но не вызывать указатели напрямую. Таким образом, функция приведения также должна работать с:
Register( a, Cast<void(int)>::From( &A::Do ));
1 ответ
Вам не нужно выделять аргументы и тип результата, чтобы снова присоединиться к ним. Просто объявите указатель на тип функции:
template <typename F, typename C>
auto Cast(F (C::*ptr)) {
return ptr;
}
Ваш желаемый синтаксис работает:
Call(a, Cast<void(std::string)>(&A::Do), "Yeeeaaa!");