我对可变参数模板函数的类型推导有问题。这是我正在尝试做的事情:
我有一个模板类,可以作为分配器使用。为了选择合适的分配器,我需要一些关于类型参数的信息。信息收集在矢量中。
创建实际元数据的函数如下所示:
template<typename T>
MetaData* create_meta() {
return new DefaultMetaData();
}
template<MyExampleType>
MetaData* create_meta() {
return new MyExampleTypeMetaData();
}
template<MyOtherType>
MetaData* create_meta() {
etc.
}
收集元数据的功能现在看起来像这样:
template<typename T, typename... Args>
void fill_meta_data(std::vector<MetaData*> &meta) {
meta.push_back(create_meta<T>());
fill_meta_data<Args...>(meta);
}
编辑:尝试清除问题:
我想像这样调用fill_meta_data
函数:
fill_meta_data<MyExampleType, MyExampleType, MyOtherType>(meta_data_vector)
因此,meta_data_vector包含MyExampleType,MyExampleType和MyOtherType的元数据
我得到的错误是“模板参数扣除/替换失败:无法推断模板参数'T'”。
我认为当它试图推断出无参数版本的参数时会出现问题,但是,我只是无法弄清楚如何定义这个默认值(它应该返回的地方)。
我已经尝试template<>
(无法识别),template<typename... Args>
(编译器说有两个实现超过0个参数)。
也欢迎针对这个问题的不同解决方案:)
谢谢!
编辑:感谢@catscradle的链接: 这是一个对我有用的解决方案:
我必须添加模板
template<typename... Args>
typename std::enable_if<sizeof...(Args) == 0>::type
fill_meta_data(std::vector<MetaData*> &meta) {}
仅在Args参数的大小为零时启用。
谢谢大家!
答案 0 :(得分:0)
您的代码中存在一些语法错误,但一旦排除它们就不会出现问题。
您的功能专长是错误的。而不是:
template<typename T>
MetaData* create_meta() {
return new DefaultMetaData();
}
template<MyExampleType>
MetaData* create_meta() {
return new MyExampleTypeMetaData();
}
尝试:
template<typename T>
MetaData* create_meta() {
return new DefaultMetaData();
}
template <>
MetaData* create_meta<MyExampleType>() {
return new MyExampleTypeMetaData();
}
另一个问题是你的递归没有最终功能。有些人发现提取递归很有帮助,因此更有意义。如果我们用某些类型绘制你的递归,我们可能会得到这个:
fill_meta_data<short, int, long> // T = short, Args... = int, long
fill_meta_data<int, long> // T = int, Args... = long
fill_meta_data<long> // T = long, Args... =
fill_meta_data<> // T = ???, Args... =
你可以看到最后一步是未定义的,因为T没有意义,但需要输入。因此,要“关闭”递归模板函数,您只需要一个常规函数重载,而不需要任何参数:
void fill_meta_data(std::vector<MetaData*> &meta) {
}
template<typename T, typename... Args>
void fill_meta_data(std::vector<MetaData*> &meta) {
meta.push_back(create_meta<T>());
fill_meta_data<Args...>(meta);
}