我有3个课程,如下:
template <typename RET, typename ARG1 = int, [...], typename ARG5 = int>
class FunctionPointer {
virtual operator()(ARG1, [...], ARG5);
};
template <typename RET, class TYPE, typename ARG1 = int, [...], typename ARG5 = int>
class ClassFunctionPointer : public FunctionPointer<RET, ARG1, [...], ARG5> {
// make it so that class functions fit here
};
template <typename RET, typename ARG1 = int, [...], typename ARG5 = int>
class GlobalFunctionPointer : public FunctionPointer<RET, ARG1, [...], ARG5> {
// make it so that non-member functions fit here
};
它们都被重载,因此每个类都可以使用可变数量的参数进行实例化,这意味着以下所有示例都是有效的:
GlobalFunctionPointer<void> a(&test1);
GlobalFunctionPointer<void, int> b(&test2);
ClassFunctionPointer<void, TestClass, int, char> c(testObject, &TestClass::test1);
ClassFunctionPointer<void, TestClass, int, char, std::string, float, SomeClass> d(testObject, &TestClass::test2);
但是对于所有这些,我写了很多代码,大约500行,请参阅here。 我发现这很难看,所以我正在寻找更优雅的解决方案。 有一个吗?
(顺便说一下,所有纠结的代码都是更复杂的事件系统的基础。)
答案 0 :(得分:4)
你正在寻找C++11's variadic templates,正是出于这个目的而发明的。
或者,让单个模板参数T
成为实际的函数类型,然后根据您的心愿,它可以是void()
,void(int)
或void(int, char)
等。
顺便说一下,std::function<T>
(或boost::function<T>
)出了什么问题?这已经全部解决了。 : - )
答案 1 :(得分:1)
如果您的编译器不支持variadic templates,那么您可以尝试使用Boost.Preprocessor库进行模拟。
检查boost :: container :: vector :: emplace_back是如何实现的: http://www.boost.org/doc/libs/1_51_0/boost/container/vector.hpp
它使用Boost.Preprocessor自动生成具有不同数量参数的函数。它会生成一些预定义的函数。
结果,您不必手动编写每个功能。相反,您只能编写一次模式。
例如:
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
struct Entity
{
#define ENTITY_PP_PARAM_LIST(z, n, data) const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n)
#define ENTITY_PP_PARAM_PASS(z, n, data) BOOST_PP_CAT(p, n)
#define BOOST_PP_LOCAL_MACRO(n) \
template<typename GenericType BOOST_PP_ENUM_TRAILING_PARAMS(n, typename P) > \
void AddComponent(BOOST_PP_ENUM(n, ENTITY_PP_PARAM_LIST, _)) \
{ \
something=new GenericType(BOOST_PP_ENUM(n, ENTITY_PP_PARAM_PASS, _)); \
} \
/**/
#define BOOST_PP_LOCAL_LIMITS (0, 3)
#include BOOST_PP_LOCAL_ITERATE()
};
预处理后扩展为:
struct Entity
{
template<typename GenericType >
void AddComponent()
{
something=new GenericType();
}
template<typename GenericType , typename P0 >
void AddComponent( const P0 & p0)
{
something=new GenericType( p0);
}
template<typename GenericType , typename P0 , typename P1 >
void AddComponent( const P0 & p0 , const P1 & p1)
{
something=new GenericType( p0 , p1);
}
template<typename GenericType , typename P0 , typename P1 , typename P2 >
void AddComponent( const P0 & p0 , const P1 & p1 , const P2 & p2)
{
something=new GenericType( p0 , p1 , p2);
}
};
P.S。我同意“轨道中的轻度赛跑”,考虑使用boost / std :: function代替。