如何在显式指定模板参数时跳过参数以指定后续参数?
如何跳过模板参数以指定后续参数?
我创建了如下函数模板prin(),但在显式指定模板参数时遇到问题——不知道怎么跳过某个模板参数去指定后面的参数。
#include <iostream> #include <vector> #include <list> #include <map> template<class T> void prinSequenceContainer (T vec){ for (auto var : vec){ std::cout << var << ' ';} } template < template <typename, typename, typename...> class T , typename T1, typename T2 , typename...T3 , typename T4> void prin( T<T1,T2,T3...> map){ std::vector<T1> vec; std::list<T2> list1; std::forward_list<T4> forward_list1; // 提取map的键和值到vector和list for ( auto it=map.begin() ; it !=map.end() ; it++ ){ vec.push_back( it->first ); list1.push_back(it->second); } // 打印容器内容 prinSequenceContainer(vec); prinSequenceContainer(list1); prinSequenceContainer(forward_list1); } int main(){ std::map<char , int> map1={ {'A' , 1}, {'B' , 2}, {'C' , 3}, {'D' , 4}, {'E' , 5}, {'F' , 6}, }; // 尝试显式指定模板参数,但失败了 prin< std::map, char, int, T3..., int >(map1); // 错误:怎么跳过T3...去指定后面的int(T4)? return 0; }
问题根源
你的模板参数设计有两个核心问题:
- 可变参数包位置错误:
typename...T3放在typename T4前面,可变参数包会“捕获”所有后续的显式参数,编译器无法区分哪些属于T3...、哪些属于T4——可变参数包必须是模板参数列表的最后一个(特殊语法场景除外)。 - T4与函数参数无关联:
T4没有和传入的map类型绑定,编译器无法自动推导它,必须显式指定,但原参数顺序让这一点无法实现。
修复方案
调整模板参数的顺序,把需要显式指定的T4放到可变参数包T3...的前面。这样编译器可以自动推导T3...(利用std::map的默认模板参数),你只需要显式指定前面的必要参数即可:
#include <iostream> #include <vector> #include <list> #include <map> #include <forward_list> // 补充原代码遗漏的头文件 template<class T> void prinSequenceContainer (T vec){ for (auto var : vec){ std::cout << var << ' ';} } // 调整参数顺序:将T4移至T3...之前 template < template <typename, typename, typename...> class T, typename T1, typename T2, typename T4, typename... T3> void prin(T<T1, T2, T3...> map){ std::vector<T1> vec; std::list<T2> list1; std::forward_list<T4> forward_list1; for ( auto it=map.begin() ; it !=map.end() ; it++ ){ vec.push_back( it->first ); list1.push_back(it->second); } prinSequenceContainer(vec); prinSequenceContainer(list1); prinSequenceContainer(forward_list1); } int main(){ std::map<char , int> map1={ {'A' , 1}, {'B' , 2}, {'C' , 3}, {'D' , 4}, {'E' , 5}, {'F' , 6}, }; // 现在可正确显式指定参数,T3...会自动推导为std::map的默认参数 prin<std::map, char, int, int>(map1); return 0; }
额外说明
- 原代码遗漏了
<forward_list>头文件,必须补充才能正常使用std::forward_list。 - 因为
forward_list1未插入任何元素,最后一行打印不会输出内容,属于正常现象。 - 若想进一步简化参数指定,可给模板参数设置默认值,但调整参数顺序是最适合初学者的直观解决方案。
内容的提问来源于stack exchange,提问作者Rango
相关产品推荐
相关产品推荐

