如何模板化c++构造函数以实现完美的转发

How to templatize C++ constructor for perfect forwarding

本文关键字:实现 完美 转发 构造函数 何模板 c++      更新时间:2023-10-16

我知道如何创建一个全局函数,使用可变模板将参数转发给类ctor(类似于shared_ptr模板类的make_shared<>):

template<typename T, typename... Args>
T Create (Args&&... args)
{
  return T(args...);  // RVO takes place here
}

是否可以使用类似的方法在类内部为静态工厂方法创建模板?我想使用类似的可变模板语法将所有参数组合转发给所有可能的构造函数(我不想重载或显式链接所有可能的变量到静态方法,只是使用模板&编译器来完成这项工作)即伪代码(!)

class Class {
public: 
static Class create(Args&&... args) 
{
     Class(args...);
}
Class(int) {} // ctor 1
Class(int, float) {} // ctor 2 
//... etc

具有类似的参数转发

如果我直接使用可变模板它看起来像这样

template <typename... Args>
class Class {
public:
    static Class create(Args&&... args)
    {
        return Class(args...);
    }
    Class(int) {} // ctor 1
    Class(int, float) {} // ctor 2
};

但是它给出了丑陋的用法语法,我需要显式地为模板提供类型…

int main()
{
    Class<int,float> a = Class<int,float>::create(1,2);
}

真的可以这样吗?

Class a = Class::create(1,2);

create函数成为模板而不是类:

class Class {
public:
    template <typename... Args>
    static Class create(Args&&... args)
    {
         //actually do perfect forwarding
        return Class(std::forward<Args>(args)...);
    }
    Class(int) {} // ctor 1
    Class(int, float) {} // ctor 2
};

现场演示

真的可以这样吗?

Class a = Class::create(1,2);

不,函数模板可以推导出它们的参数,但是你把Class写成一个类模板,你不能推导出类模板的模板参数。

你不能只说Class而不说明Class的哪个专门化,你也不能创建Class类型的变量,因为Class不是一个类型,它是一个模板,即一个可能的类型族。

你可以创建一个自由的函数来做这件事:

template<typename... Args>
  inline
  Class<typename std::decay<Args>::type...>
  create_Class(ARgs&&... args)
  {
    return Class<typename std::decay<Args>::type...>{ std::forward<Args>(args)... };
  }

注意:我添加了完美转发,你在问题标题中提到的,但没有在任何地方使用。

现在你可以这样做:

auto a = create_Class(1, 2);

这将创建一个Class<int, int>对象。

但是也许你一开始就不想让Class成为模板?