重载成员函数指针的转换助手
cast helper for overloaded member function pointer
我想对指向方法的指针进行 "nicer" 转换操作。
Given 是一个 class 具有重载的成员函数和一个模板,它吃掉各种成员指针和对象并简单地调用它们。
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");
所以我想让演员阵容更容易阅读,所以得到了这个帮手 class:
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");
问:
是否可以使我的 class Cast
成为模板函数,以便更轻松地获取转换调用的语法?我想要这样的东西:
Call( a, Cast<void(std::string)>( &A::Do ), "Yeeeaaa!");
但是我找不到这样写模板函数的方法,因为我写的任何一种专业化都是不允许的。
允许使用任何类型的 c++。如果 C++17 给出了新的方法,请告诉我!
为什么我不能在调用函数中使用 lambda 的参数:
我的真实代码只需要注册指针而不直接调用指针。所以 cast 函数也必须适用于:
Register( a, Cast<void(int)>::From( &A::Do ));
您不必为了再次加入参数和结果类型而将它们分开。只需声明一个指向函数类型的成员指针:
template <typename F, typename C>
auto Cast(F (C::*ptr)) {
return ptr;
}
您想要的语法有效:
Call(a, Cast<void(std::string)>(&A::Do), "Yeeeaaa!");
我想对指向方法的指针进行 "nicer" 转换操作。
Given 是一个 class 具有重载的成员函数和一个模板,它吃掉各种成员指针和对象并简单地调用它们。
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");
所以我想让演员阵容更容易阅读,所以得到了这个帮手 class:
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");
问:
是否可以使我的 class Cast
成为模板函数,以便更轻松地获取转换调用的语法?我想要这样的东西:
Call( a, Cast<void(std::string)>( &A::Do ), "Yeeeaaa!");
但是我找不到这样写模板函数的方法,因为我写的任何一种专业化都是不允许的。
允许使用任何类型的 c++。如果 C++17 给出了新的方法,请告诉我!
为什么我不能在调用函数中使用 lambda 的参数:
我的真实代码只需要注册指针而不直接调用指针。所以 cast 函数也必须适用于:
Register( a, Cast<void(int)>::From( &A::Do ));
您不必为了再次加入参数和结果类型而将它们分开。只需声明一个指向函数类型的成员指针:
template <typename F, typename C>
auto Cast(F (C::*ptr)) {
return ptr;
}
您想要的语法有效:
Call(a, Cast<void(std::string)>(&A::Do), "Yeeeaaa!");