简体   繁体   English

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

[英]How to templatize C++ constructor for perfect forwarding

I know how to create a global function that forwards arguments to class ctor using variadic templates (its similar to make_shared<> for shared_ptr template class): 我知道如何创建一个全局函数,使用可变参数模板将参数转发给类ctor(类似于shared_ptr模板类的make_shared <>):

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

Is it possible to use similar approach to create template for static factory method inside the class? 是否可以使用类似的方法为类中的静态工厂方法创建模板? I want to use similar variadic templates syntax to forward all arguments combinations to all possible constructors (I'd like to NOT overload or explicitly link all possible ctors to static methods and just use the templates & compiler to do this work) ie in pseudocode (!) 我想使用类似的可变参数模板语法将所有参数组合转发给所有可能的构造函数(我不想重载或显式地将所有可能的ctors链接到静态方法,只需使用模板和编译器来完成这项工作)即在伪代码中( !)

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

to have similar forwarding of arguments 有类似的参数转发

If I use variadic template directly it looks like this 如果我直接使用variadic模板,它看起来像这样

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

but it gives ugly usage syntax, where I need explicitly provide types to the template... 但它提供了丑陋的使用语法,我需要明确地为模板提供类型...

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

Can it be just like this ?? 可以这样吗?

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

Just make the create function a template rather than the class: 只需将create function设为模板而不是类:

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
};

Live Demo 现场演示

Can it be just like this ?? 可以这样吗?

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

No, function templates can deduce their arguments, but you wrote Class as a class template and you cannot deduce template arguments for class templates. 不,函数模板可以推断出它们的参数,但是您将Class编写为类模板,并且不能推断类模板的模板参数。

You cannot just say Class without saying which specialization of Class you mean, and you cannot create a variable of type Class , because Class is not a type, it's a template, ie a family of possible types. 你不能只说Class而不说你所指的Class哪种特殊化,你不能创建Class类型的变量,因为Class不是一个类型,它是一个模板,即一系列可能的类型。

You can create a free function to do it though: 你可以创建一个免费的功能来做到这一点:

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)... };
  }

NB I added perfect forwarding, which you mentioned in your question title but failed to use anywhere. NB我添加了完美转发,你在问题标题中提到但未能在任何地方使用。

Now you can do: 现在你可以这样做:

auto a = create_Class(1, 2);

This will create a Class<int, int> object. 这将创建一个Class<int, int>对象。

But maybe you didn't want to make Class a template in the first place? 但也许你最初不想让Class成为模板?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM