如何为模板模板参数指定默认值?
如何为模板模板参数指定默认值?
嘿,这个问题问得很到位!其实给模板模板参数设置默认值的语法并不复杂,只要在声明模板参数时直接加上= std::unordered_map就行,不过有几个细节得注意下:
先看你原来的函数模板声明:
template <template <typename K, typename V> typename Map> void foo();
要给Map指定默认的std::unordered_map,只需要修改模板参数的声明部分,变成这样:
template <template <typename K, typename V> typename Map = std::unordered_map> void foo();
这里有个容易忽略的小细节:std::unordered_map实际上有5个模板参数,除了K和V,还有哈希函数、相等比较器、分配器,这三个都有默认值。但你的模板模板参数只声明了前2个参数,这完全没问题——因为当你用std::unordered_map作为默认实参时,它的后续默认参数会自动补全,只要你的模板模板参数的参数列表和目标模板的前N个参数匹配就可以(这里N是你声明的2个)。
如果想要更严谨,也可以把模板模板参数的参数列表和std::unordered_map的完整参数对应上,比如:
#include <functional> #include <memory> template < template < typename K, typename V, typename Hash = std::hash<K>, typename Eq = std::equal_to<K>, typename Alloc = std::allocator<std::pair<const K, V>> > typename Map = std::unordered_map > void foo();
不过大多数场景下,第一种简化写法就足够用了,毕竟我们很少需要显式覆盖那些默认参数。
最后给你一个完整的可编译示例,方便你直观理解:
#include <unordered_map> #include <map> #include <iostream> #include <type_traits> template <template <typename K, typename V> typename Map = std::unordered_map> void foo() { Map<int, std::string> my_map; my_map[1] = "hello"; my_map[2] = "world"; // 打印容器类型提示,方便验证 if constexpr (std::is_same_v<Map<int, std::string>, std::unordered_map<int, std::string>>) { std::cout << "当前使用默认的std::unordered_map\n"; } else if constexpr (std::is_same_v<Map<int, std::string>, std::map<int, std::string>>) { std::cout << "当前显式指定使用std::map\n"; } } int main() { foo(); // 默认触发std::unordered_map版本 foo<std::map>; // 显式指定使用std::map版本 return 0; }
总结几个核心点:
- 给模板模板参数设默认值的核心语法是在模板参数声明后加
= 目标模板 - 模板模板参数的参数列表只需和目标模板的前N个参数匹配,目标模板的后续默认参数会自动生效
内容来源于stack exchange
相关产品推荐
相关产品推荐

