尝试展开模板参数包时出错
Error when trying to expand template parameter pack
我正在尝试使用可变模板将参数类型存储到成员函数中。我试图实现这一点的方法是将每个类型与一个键关联起来,然后将这个键存储在std::vector中。创建此密钥的代码如下
template <typename T>
class ClassInfo {
public:
inline static void const* GetClassKey() {
static char key;
return &key;
}
};
然后,我使用以下代码尝试将密钥存储在std::vector 中
class WrappedMemberFunction {
void *function_pointer; // Holds the member function pointer
void const* class_type; // Class type key
void const* return_type; // Return type key
std::vector<void const*> parameter_types; // Parameter type keys
void StoreArguments() {}
template <typename Arg, typename... Args>
void StoreArguments() {
parameter_types.push_back(ClassInfo<Arg>::GetClassKey());
StoreArguments<Args...>(); // Error here: No matching member function for call to 'StoreArguments'
}
public:
template <typename Class, typename ReturnType, typename... Args>
WrappedMemberFunction(ReturnType (Class::*member_pointer)(Args...)) {
// Store member pointer as regular old void pointer
function_pointer = (void*&)member_pointer;
// Store class type
class_type = ClassInfo<Class>::GetClassKey();
// Store return type
return_type = ClassInfo<Class>::GetClassKey();
// Store parameter types
StoreArguments<Args...>();
}
};
我一直纠结于存储每个类键所需的可变递归。我在上面指出的行中得到一个错误,这是试图扩展参数包的递归步骤。我在这里做错了什么?
您有:
// function that is not a template
void StoreArguments() {}
// function template that takes N+1 types
template <typename Arg, typename... Args>
void StoreArguments() {
parameter_types.push_back(ClassInfo<Arg>::GetClassKey());
// call function template that takes N types
StoreArguments<Args...>();
}
希望我添加的评论能说明这一点。。。您正在从一个采用N+1种类型的函数模板递归到一个采用N种类型的功能模板。基本情况是有一个采用0类型的函数模板。你没有,你有一个空函数——这不会被考虑。
您的方法是将类型提升为值,因此您的基本情况实际上是一个null函数:
template <class T> struct tag { using type = T; };
void StoreArgumentsImpl() { }
template <typename Arg, typename... Tags>
void StoreArgumentsImpl(tag<Arg>, Tags... tags) {
parameter_types.push_back(ClassInfo<Arg>::GetClassKey());
StoreArgumentsImpl(tags...);
}
template <typename... Args>
void StoreArguments() {
StoreArgumentsImpl(tag<Args>{}...);
}
或者使用扩展器技巧在单个函数中完成所有操作:
template <typename... Args>
void StoreArguments() {
using expander = int[];
(void)expander{0,
(void(
parameter_types.push_back(ClassInfo<Args>::GetClassKey())
), 0)...
};
}
或者,在C++17中(迫不及待),使用折叠表达式:
template <typename... Args>
void StoreArguments() {
(parameter_types.push_back(ClassInfo<Args>::GetClassKey()), ...);
}
或者,在C++17中,使用if constexpr(尽管这不适用于无参数):
template <typename Arg, typename... Args>
void StoreArguments() {
parameter_types.push_back(ClassInfo<Args>::GetClassKey());
if constexpr(sizeof...(Args) > 0) {
StoreArguments<Args...>();
}
}
相关文章:
- 如何反转整数参数包
- 如何将enable-if与模板参数和参数包一起使用
- 实例化模板时,我是否必须显式显示参数包中的类型?
- 当模板类使用参数包时,如何传递其他模板参数
- 在if constexpr中使用带参数包的概念时,升级到gcc 9后出现编译错误
- 模板 使用数据数组调用函数时扩展参数包
- 将代码移出类定义时未扩展参数包
- 在运行时C++11 个索引模板参数包,以便访问第 N 种类型
- 当将参数包传递给另一个可变参数模板函数时,我是否必须使用 std::forward
- 在 lambda 中捕获参数包时,某些整数会丢失其值
- 尝试使用参数包绑定 std::function 时获取未声明的参数
- 使用 "using declaration" 扩展非类型模板参数包(模板可变参数编译时 SignalSlot 实现)
- 在运行时根据某些元数据强制转换参数包值
- 当可变参数模板类继承自模板参数时,在调用基类型的方法时扩展参数包
- 根据模板参数包的大小生成编译时码
- 覆盖使用模板参数包扩展声明的虚拟方法时遇到问题
- 在处理函数的部分模板专门化时,类型定义和参数包展开问题
- 当参数是函数参数包时,在部分排序期间推导模板参数
- 尝试展开模板参数包时出错
- 当涉及参数包时,我是否可以依赖具有默认值的参数类型被推断为空包