我有这个功能:
template <class T>
T *allocate()
{
T *obj = new(top) T();
top += sizeof(T);
return obj;
}
现在,它可以很好地创建具有默认构造函数的对象,但是如何创建需要传递新参数的对象?
我知道可以使用C ++ 11的可变参数template
来实现,但是如果没有C ++ 11功能,我怎么能这样做呢? (显然我的VS2012版本还不支持这个功能,但我想知道如果没有这个功能,即使升级会修复它也不知道怎么做)
答案 0 :(得分:4)
没有替代可变参数模板的语言功能(当然,否则它们不会被发明)。
您可以提供多个接受最多N
个参数的重载(合理选择N
)。每个重载都会完美地将其参数转发给T
的构造函数。
除了你的nullary函数模板:
template <class T>
T *allocate()
{
T *obj = new(top) T();
top += sizeof(T);
return obj;
}
您将拥有一元函数模板:
template <class T, class P1>
T *allocate(P1&& p1)
{
T *obj = new(top) T(std::forward<P1>(p1));
top += sizeof(T);
return obj;
}
二元函数模板:
template <class T, class P1, class P2>
T *allocate(P1&& p1, P2&& p2)
{
T *obj = new(top) T(std::forward<P1>(p1), std::forward<P2>(p2));
top += sizeof(T);
return obj;
}
三元函数模板:
template <class T, class P1, class P2, class P3>
T *allocate(P1&& p1, P2&& p2, P3&& p3)
{
T *obj = new(top) T(std::forward<P1>(p1), std::forward<P2>(p2),
std::forward<P3>(p3));
top += sizeof(T);
return obj;
}
等等(你明白了)。如果你介意代码复制,你可以找出一些可以减轻痛苦的宏 - 但是它们并没有消除它,特别是如果你不喜欢宏。
不要忘记:
#include <utility>
有权访问std::forward<>()
。
答案 1 :(得分:1)
这不仅仅是您需要的可变参数模板,还有C ++ 11的完美转发功能。
如果您没有C ++ 11功能,可以伪造它,至少对参数数量设置限制。但这并不容易或漂亮。有关示例,请参阅boost::tuple
的提升实现。
答案 2 :(得分:1)
如果您使用提升,则可以使用boost::in_place_factory
代替http://www.boost.org/doc/libs/1_35_0/libs/utility/in_place_factories.html
template <class InplaceFactory>
T *allocate(InplaceFactory const & fac)
{
T *obj = reinterpret_cast<T*>(top);
fac.template apply<T>(obj)
top += sizeof(T);
return obj;
}
并使用:
T * a = allocate(boost::in_place(val, boost::ref(ref_value)));
<强> PS 强> 不这样做:
T * a = allocate(boost::in_place());
您可以添加重载:
T *allocate(){ return allocate(boost::in_place()); }
答案 3 :(得分:0)
如果您不想使用varadic模板,则可能需要对此进行设计点击:
struct empty {};
template<typename ObjectType,unsigned int ARG_LENGTH = 0,
typename arg0=empty,
typename arg1=empty,
typename arg2=empty,
typename arg3=empty,
typename arg4=empty>
ObjectType* allocate(const arg0& a0,
const arg1& a1,
const arg2& a2,
const arg3& a3,
const arg4& a4){
ObjectType * obj = 0;
switch(ARG_LENGTH){
case 0: obj = new(top) ObjectType();break;
case 1: obj = new(top) ObjectType(arg0);break;
case 2: obj = new(top) ObjectType(arg0,arg1);break;
case 3: obj = new(top) ObjectType(arg0,arg1,arg2);break;
case 4: obj = new(top) ObjectType(arg0,arg1,arg2,arg3); break;
default: obj = new(top) ObjectType(); break;
}
top += sizeof(T);
return obj;
}
不确定是否会编译,但你明白了。