如何实现模板函数来创建任意类实例?

时间:2017-07-04 19:25:12

标签: c++ function constructor reference variadic-templates

我需要实现一个模板函数,它允许我使用任意构造函数创建任意类的实例,其中任何可能的参数都可以是左值和右值的任意组合。

假设我有两个类--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);
}

有人可以建议一个可能的解决方案吗?

2 个答案:

答案 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