【发布时间】:2018-07-29 23:56:39
【问题描述】:
这更多是我正在考虑的设计约束。如果您想知道语法,则此代码的 sn-p 是针对虚幻引擎的 - 但这应该与问题无关。
此模板代码仅采用用户想要实例化的对象类型 - 然后创建一个拥有容器对象并调用所有者的 add 方法。 (实际构建逻辑由业主负责)
template<typename T>
void UEntityFactory::Create_Impl(AEntityObject* owner)
{
static_assert( TPointerIsConvertibleFromTo<T, UEntity>::Value, "[UEntityFactory] ERROR: Attempting to create a non-entity type");
owner->AddEntity<T>();
}
// Templated create accepting variadic arguments; it first creates the housing entity object
// and then recursively generates code for each argument.
template <typename T, typename...Args>
AEntityObject* UEntityFactory::Create()
{
// Create the owning EntityObject
AEntityObject* obj = NewObject<AEntityObject>(this);
Create_Impl<T>(obj);
// Recursively call Create_Impl for Args
Create_Impl<Args...>(obj);
return obj;
}
根据我从模板参数包中了解到的情况,可变参数(在我的例子中是 ...Args)是可选的。拥有两个类型名而不是一个参数包的基本原理是确保用户至少传递一个模板参数。
我想限制创建过程以确保始终创建有效对象。但是如果我调用如下行,上面的代码不会编译:
AEntityObject* obj = factory.Create<EntityA>();
我认为我设置模板声明的方式需要另一个参数。 错误如下:
- '
UEntityFactory::Create_Impl': 找不到匹配的重载函数 - 注意:请参阅正在编译的函数模板实例化“
AEntityObject *UEntityFactory::Create<UDebugEntityA,>(void)”的参考 - '
void UEntityFactory::Create_Impl(AEntityObject *)': 无法推断出'T'的模板参数
这是其中一个错误,我有点知道它为什么会发生,但我无法清楚地表达它。果然,如果我将 Create 函数的声明更改为以下,它编译得很好:
template <typename...Args>
AEntityObject* UEntityFactory::Create()
{
AEntityObject* obj = NewObject<AEntityObject>(this);
// Recursively call Create_Impl for Args
Create_Impl<Args...>(obj);
return obj;
}
然而这意味着,用户现在可以写
AEntityObject* obj = factory.Create<>();
这是我想要避免的。有没有一种优雅的方法来强制至少一个模板参数,以及一个可选的 set variadic 参数?我不能重载 Create 方法,因为这会产生不明确的调用。
编辑:我搞砸了,我错误地认为我的参数一开始就正确展开 - 感谢 Jarod42 的纠正。
【问题讨论】:
-
template <typename Arg, typename ... Args>怎么样?
标签: c++ variadic-templates template-meta-programming