I want to accomplish the following:
Entity e;
e.AddComponent<CPosition>(128, 128); //method should instantiate a new CPosition(128,128)
e.AddComponent<CSprite>(some, other, args); //etc
The important part is the AddComponent method. It should attempt to construct the generic type with the arguments passed. I believe C++11's variadic templates to forward the arguments to the constructor. However, I do not have access to this functionality yet (VS2010).
Does anyone have any idea on how to do this?
Write a bunch of overloads, each taking a different number of parameters.
class Entity
{
public:
template<typename T>
void AddComponent() { component_ = new T(); }
template<typename T, typename T1>
void AddComponent(T1 t1) { component_ = new T(t1); }
template<typename T, typename T1, typename T2>
void AddComponent(T1 t1, T2 t2) { component_ = new T(t1, t2); }
// etc
...
};
Check how boost::container::vector::emplace_back is implemented: http://www.boost.org/doc/libs/1_51_0/boost/container/vector.hpp
It uses Boost.Preprocessor for auto-generation of functions taking different number of arguments. It generates some predefined number of functions.
As the result, you don't have to write each overload by hands. Instead, you can write your pattern only once.
For instance:
#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()
};
After preprocessing expands to:
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);
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With