具有单参数模板的成员函数包装器
Member function wrapper with a single argument template?
我制作了一个模板函数,它将一个成员函数作为参数。
然而,由于在将类用作成员函数参数的一部分之前,必须声明该类,因此我必须将其作为一个单独的参数:
template<typename C, void (C::*Method)(void)>
function<void(C*)> methodWrap()
{
}
这意味着当显式实例化模板时(我希望这些包装器在编译时生成,而不是将成员指针作为参数传入),我在使用它时必须键入两次:
function<void(C*)> someFunc = wrapMethod<SomeClass, &SomeClass::someMethod>();
为什么我不能写这样的东西:
template<void (C::*Method)(void)>
function<void(C*)> methodWrap()
{
}
并让它捕获C的类型及其成员函数指针,而不必键入SomeClass两次?
或者为什么我不能把它包装在一个外部模板中,该模板声明C为"自由变量",然后有一个内部模板参数来执行推导
template<typename C>
template<void (C::*Method)(void)>
function<void(C*)> methodWrap()
{
}
如果您可以为成员函数指针使用一个普通函数参数,而不是将其作为模板参数,那么您可以执行
#include <functional>
template<typename R, typename C, typename... Args>
struct MemberFunctionPointer
{
typedef R Return;
typedef C Class;
};
template<typename R, typename C>
constexpr auto inferMemberFunctionPointer(R (C::*method)())
{
return MemberFunctionPointer<R,C>{};
}
template<typename T>
constexpr auto methodWrap(T m)
{
typedef typename decltype(inferMemberFunctionPointer(m))::Class Class;
typedef typename decltype(inferMemberFunctionPointer(m))::Return Return;
return std::function<Return (Class*)>();
}
struct B {};
struct A
{
B f();
};
void foo()
{
auto const m = methodWrap( &A::f );
}
std::function
不是constexpr
类型,因此我们不能使用methodWrap初始化constexpr
变量。您可以通过创建自己的简单constexpr
成员函数包装器来绕过此问题。我还添加了一个static_assert
以获得更好的错误消息。
#include <functional>
template<typename R, typename C, typename... Args>
struct MemberFunctionPointer
{
typedef R Return;
typedef C Class;
};
template<typename R, typename C>
constexpr auto inferMemberFunctionPointer(R (C::*method)() const)
{
return MemberFunctionPointer<R,C>{};
}
template<typename R, typename C>
struct MemberFunction
{
constexpr explicit MemberFunction(R (C::*g)() const): f(g) {}
constexpr R operator()(C const* obj) const
{
return (obj->*f)();
}
R (C::*f)() const;
};
template<typename T>
constexpr auto methodWrap(T m)
{
static_assert( std::is_member_function_pointer<T>::value,
"Member function pointer expected!");
typedef typename decltype(inferMemberFunctionPointer(m))::Class Class;
typedef typename decltype(inferMemberFunctionPointer(m))::Return Return;
return MemberFunction<Return, Class>{ MemberFunctionPointer<Return,Class>{} };
}
struct B {};
struct A
{
constexpr B f() const;
};
void foo()
{
auto constexpr m = methodWrap( &A::f );
auto constexpr a = A{};
m( &a );
auto b = A{};
m( &b );
}
为什么我不能写这样的东西:
template<void (C::*Method)(void)> function<void(C*)> methodWrap()
因为这里没有办法确定C
的类型。因此需要CCD_ 7。
或者为什么我不能将它封装在一个外部模板中,该模板将C声明为"自由变量",然后有一个内部模板参数执行扣除
我不知道这对你的困境有什么帮助。您仍然需要一种方法来在模板参数列表中指定对象的类型。
你可以这样做:
template<typename C>
std::function<void(C&)> wrap(void(C::*mf)())
{
return std::function<void(C&)>(mf);
}
用法:wrap(&Obj::memfun);
当然,要通过指针实际调用非静态成员函数,需要一个实例对象。
相关文章:
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法