我需要实现一个模板函数,它允许我使用任意构造函数创建任意类的实例,其中任何可能的参数都可以是左值和右值的任意组合。
假设我有两个类--A和B - 如下:
class A
{
public:
A(){}
};
class B
{
A& a1; // I want to be able to call non-constant methods and modify object
const A& a2; // This I need only as const member
int i; //can be initialized with a temporary object
public:
B(A& a1_, const A& a2_, int i_) : a(a_), a2(a2_), i(i_) {}
};
我试图实现类似下面的东西,但它只允许我使用左值(命名对象),我将无法传递临时对象。 添加const关键字部分解决了问题,但不允许修改可能需要的对象。
template <typename TType, typename ... TArgs>
TType create(TArgs&... args)
{
return TType(args...);
}
我想使用'create'这样的函数:
int main()
{
A a1;
A a2;
//function takes both lvalue and rvalue
B b = create<B>(a1, a2, 1);
}
有人可以建议一个可能的解决方案吗?
答案 0 :(得分:2)
如上面Alan Stokes所述,您可以使用forwarding references来接收左值和右值表达式:
template <typename TType, typename ... TArgs>
TType create(TArgs&&... args)
{
return TType(std::forward<TArgs>(args)...);
}
答案 1 :(得分:0)
有人可以建议一个可能的解决方案吗?
你只是有一些错别字。特别是,您不需要将非const
引用的所有参数作为TArgs&
传递给create()
函数。编译器已匹配最佳拟合类型(引用)。
class B
{
A& a1; // I want to be able to call non-constant methods and modify object
const A& a2; // This I need only as const member
int i; //can be initialized with a temporary object
public:
B(A& a1_, const A& a2_, int i_) : a1(a1_), a2(a2_), i(i_) {}
// ^ ^ ^
};
template <typename TType, typename ... TArgs>
TType create(TArgs... args)
// ^ Remove the reference here
{
return TType(args...);
}
int main()
{
A a1;
const A a2;
// ^^^^^
//function takes both lvalue and rvalue
B b = create<B>(a1, a2, 1);
}
请参阅完整编译版本live here。
当然使用移动参考as stated in other answers/comments也可以修复错误(除了a
错误a1
之外的错误。):
template <typename TType, typename ... TArgs>
TType create(TArgs&&... args)
{
return TType(std::forward<TArgs>(args)...);
}
查看另一个live example。