C++:我可以在模板参数包中强制执行至少1个agment吗
C++: Can I enforce at least 1 agument in a template parameter pack
这更像是我正在考虑的设计约束。这段代码针对的是虚幻引擎,以防您对语法感到疑惑,但这应该与问题无关。
这个模板代码只需获取用户想要实例化的对象类型,然后创建一个拥有的容器对象,并对所有者调用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<>();
这就是我想要避免的。有没有一种优雅的方法可以强制至少一个模板参数,以及一个可选的集变量参数?我不能重载Create方法,因为这将创建一个不明确的调用。
编辑:我搞砸了,我错误地认为我的参数一开始就正确展开了——感谢Jarod42的更正。
好吧,你只需要添加一个static_assert()
来进行检查,还可以发出一个更有意义的编译时错误:
template <typename...Args>
AEntityObject* UEntityFactory::Create()
{
static_assert(sizeof...(Args) > 0, "Create() would like to have at least one object type to create...");
AEntityObject* obj = NewObject<AEntityObject>(this);
// Recursively call Create_Impl for Args
Create_Impl<Args...>(obj);
return obj;
}
template <typename T, typename...Args>
AEntityObject* UEntityFactory::Create()
{
// [..]
// Recursively call Create_Impl for Args
Create_Impl<Args...>(obj);
}
不是递归调用
因此,事实上,您似乎很难在可变模板上迭代。
然后您可以使用:
template <typename T, typename...Args>
AEntityObject* UEntityFactory::Create()
{
// Create the owning EntityObject
AEntityObject* obj = NewObject<AEntityObject>(this);
Create_Impl<T>(obj);
// C++17: folding expression
(Create_Impl<Args>(obj), ...);
return obj;
}
和之前:
template <typename T, typename...Args>
AEntityObject* UEntityFactory::Create()
{
// Create the owning EntityObject
AEntityObject* obj = NewObject<AEntityObject>(this);
Create_Impl<T>(obj);
const int dummy[] = { 0, (Create_Impl<Args>(obj), 0)...};
static_cast<void>(dummy); // Avoid warning for unused variable
return obj;
}
相关文章:
- 按 Tab 单步执行两个控制组
- 如何在 Qt5 中执行多个 QProcess
- 在C++中,如何在第一个"system()"结束后执行第二个"system()"?
- 在 Radeon 卡上并行执行多个 OpenCL 内核
- 如何对模板类型强制执行常量
- C++:我可以在模板参数包中强制执行至少1个agment吗
- 在 MySQL 连接器C++ API 中使用一个函数调用执行多个查询的正确方法是什么?
- 编译器未强制执行返回协定
- 如何在 Linux 上强制执行矢量下标超出范围的调试断言
- 如何使用C++模板强制执行正式协议?
- 如何在R和C 中分别执行两个矩阵的矩阵产物
- 为什么在与静态库链接时强制执行 order(例如 source.cxx -lstatic)
- 如何执行两个函数参数具有相同的模板类型
- C++中更快地执行两个程序的可能解释(使用 Python 比较)?
- 当函数在 GCC 中没有任何返回时,如何强制执行错误?
- 使file执行多个程序(C/C )
- 强制执行执行顺序
- 执行三个嵌套for循环的最快方法是什么
- 替换decorator模式以强制执行创建顺序
- 如何使用'#define';定义一个宏来执行多个方法