如何模板化 C++ 构造函数以实现完美转发
How to templatize C++ constructor for perfect forwarding
我知道如何使用可变参数模板创建一个将参数转发给 class ctor 的全局函数(它类似于 make_shared<> 用于 shared_ptr 模板 class) :
template<typename T, typename... Args>
T Create (Args&&... args)
{
return T(args...); // RVO takes place here
}
是否可以使用类似的方法在 class 中为静态工厂方法创建模板?我想使用类似的可变参数模板语法将所有参数组合转发给所有可能的构造函数(我不想重载或显式 link 所有可能的构造函数到静态方法,只使用模板和编译器来完成这项工作)
即在伪代码 (!)
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);
Can it be just like this ??
Class a = Class::create(1,2);
不,函数模板可以推导它们的参数,但是你将 Class
写成 class 模板,你不能推导 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)... };
}
N.B。我添加了完美转发,你在问题标题中提到但没有在任何地方使用。
现在你可以做:
auto a = create_Class(1, 2);
这将创建一个 Class<int, int>
object。
但也许您一开始就不想制作 Class
模板?
只需将 create
函数设为模板而不是 class:
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 ctor 的全局函数(它类似于 make_shared<> 用于 shared_ptr 模板 class) :
template<typename T, typename... Args>
T Create (Args&&... args)
{
return T(args...); // RVO takes place here
}
是否可以使用类似的方法在 class 中为静态工厂方法创建模板?我想使用类似的可变参数模板语法将所有参数组合转发给所有可能的构造函数(我不想重载或显式 link 所有可能的构造函数到静态方法,只使用模板和编译器来完成这项工作) 即在伪代码 (!)
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);
Can it be just like this ??
Class a = Class::create(1,2);
不,函数模板可以推导它们的参数,但是你将 Class
写成 class 模板,你不能推导 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)... };
}
N.B。我添加了完美转发,你在问题标题中提到但没有在任何地方使用。
现在你可以做:
auto a = create_Class(1, 2);
这将创建一个 Class<int, int>
object。
但也许您一开始就不想制作 Class
模板?
只需将 create
函数设为模板而不是 class:
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
};