我想模仿std::function
模板参数,但我不知道它是如何工作的。
请考虑以下代码:
std::function<int(int)> p;
如何编写模仿此模板参数<int(int)>
?
template<typename ...> <-- what should be here instead of `...`
MyClass
我真正想要实现的是我希望能够将typedef <int(int)>
作为函数指针,并且我希望它不仅适用于int (*func)(int)
函数。
我正在努力实现这样的目标:
SomeSmartStruct<MyClass, int(int)>::MemFuncPointerType pMemFunc;
我希望MemFuncPointerType
属于以下类型:
int (__thiscall MyClass::* )(int)
和
SomeSmartStruct<MyClass, int(int)>::FunctionPointer pFunc;
应为此类型:
int (__cdecl *)(int)
我正在使用VS2010,因此并非所有C ++ 11功能都受支持,但它确实实现了std::function
。
答案 0 :(得分:2)
使用可变参数模板:
template <typename C, typename T>
struct make_member_function_pointer;
template <typename C, typename R, typename... Args>
struct make_member_function_pointer<C,R(Args...)>
{
using type = R(C::*)(Args...);
};
没有可变参数模板:
template <typename T> struct identity { typedef T type; };
template <typename C, typename T>
struct make_member_function_pointer;
template <typename C, typename R, typename Arg1>
struct make_member_function_pointer<C,R(Arg1)> : identity<R(C::*)(Arg1)> {};
template <typename C, typename R, typename Arg1, typename Arg2>
struct make_member_function_pointer<C,R(Arg1,Arg2)> : identity<R(C::*)(Arg1,Arg2)> {};
template <typename C, typename R, typename Arg1, typename Arg2, typename Arg3>
struct make_member_function_pointer<C,R(Arg1,Arg2,Arg3)> : identity<R(C::*)(Arg1,Arg2,Arg3)> {};
用法:的
template <typename T, typename F>
struct SomeSmartStruct
{
typedef typename make_member_function_pointer<T,F>::type MemFuncPointerType;
typedef F* FunctionPointer;
};
试验:
struct MyClass
{
int foo(int) {return 0;}
};
int bar(int) {return 0;}
int main()
{
SomeSmartStruct<MyClass, int(int)>::MemFuncPointerType pMemFunc = &MyClass::foo;
SomeSmartStruct<MyClass, int(int)>::FunctionPointer pFunc = &bar;
}
<强>更新强>
我可以以某种方式利用预处理器自动生成make_member_function_pointer的部分特化吗?我已经看到使用BOOST_PP_ITERATION做了类似的事情,但我不知道它是如何工作的。
不确定
#include <boost/preprocessor.hpp>
template <typename T> struct identity { typedef T type; };
template <typename C, typename T>
struct make_member_function_pointer;
#define BOOST_PP_LOCAL_MACRO(n)\
template <typename C, typename R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Arg)>\
struct make_member_function_pointer<C,R(BOOST_PP_ENUM_PARAMS(n, Arg))> : identity<R(C::*)(BOOST_PP_ENUM_PARAMS(n, Arg))> {};
#define BOOST_PP_LOCAL_LIMITS (0, 20) // 20 is the limit of params
#include BOOST_PP_LOCAL_ITERATE()
试验:
int bar10(int,int,int,int,int,int,int,int,int,int) {return 0;}
SomeSmartStruct<MyClass, int(int,int,int,int,int,int,int,int,int,int)>::FunctionPointer pFunc10 = &bar10;
答案 1 :(得分:2)
int(int)
只是一种类型,因此可以与template <typename T>
匹配。
当然太通用了:
template<typename T>
struct Pointer
{
typedef T* type;
};
然后你可以做
int foo(int i) {return i;}
int main() {
Pointer<int(int)>::type f = &foo;
}