接收通用映射作为参数的模板函数
可能有很多情况下,我们想要在与映射类型无关的std::map
或std::unordered_map
上执行某种操作,该操作完全相同。让我们看看下面的例子:接收通用映射作为参数的模板函数
#include <map>
#include <unordered_map>
#include <iostream>
template< template <typename,typename> class Container >
void printMap(Container<int, long> inputMap, bool additionalParam = false)
{
for (const pair<int,long> p : inputMap)
cout<<p.first <<","<< p.second <<std::endl;
}
int main()
{
int a = 1;
long b = 2;
map<int,long> map1;
map1.emplace(a,b);
unordered_map<int,long> map2;
map2.emplace(a,b);
printMap(map1);
printMap(map2);
return EXIT_SUCCESS;
}
如果我尝试编译上面的例子,我有这样的:
error: no matching function for call to ‘printMap(std::map<int, long int>&)’
我读到这个post使用模板的模板。什么是正确的方法来做到这一点?
尝试
template< template <typename...> class Container, typename ... Ts >
void printMap(Container<int, long, Ts...> inputMap,
bool additionalParam = false)
的(大)的问题在你的代码是std::map
和std::unordered_map
是模板类有四个(而不是两个)模板参数。第3和第4个有默认值,所以你可以定义一个std::map
对象
std::map<int, long> map1;
但是,使用默认参数,你将它定义为
std::map<int, long, std::less<int>,
std::allocator<std::pair<const int, long> >> map1;
(PS:或者你可以把它简单并且使用auto
,如在Semyon Burov的解决方案中; +1)
编译器不能推导出模板参数,如果你这样定义的话。 尝试使用:
template<typename Map>
void printMap(const Map& map, bool additionalParam = false) {
for (const auto& p : map)
cout<<p.first <<","<< p.second <<std::endl;
}
如果需要检查,也Map
正是Map<int, long int>
,然后添加静态断言的函数体:
static_assert(std::is_same< typename Map::key_type, int >::value &&
std::is_same< typename Map::mapped_type, long >::value, "!");
我添加了一个'static_assert'来维护类型约束。 –
@HenriMenke个人而言,我没有看到能够打印任何类型的地图而不是'Map
我也没有,但它是问题的一部分,地图专用于'int'和'long'。 –
试试这个:
template<class Container>
void printMap(const Container& inputMap)
{
using Key = typename Container::key_type;
using Value = typename Container::mapped_type;
for (const std::pair<Key,Value> p : inputMap)
std::cout << p.first << "," << p.second << std::endl;
}
或更好,只是:
template<class Container>
void printMap(const Container& inputMap)
{
for (const auto& p : inputMap)
std::cout << p.first << ","<< p.second << std::endl;
}
@EdgarRokyan:哦,是的,没关系,我只是有点说明了一点。但是,是的。 – einpoklum
['std :: map'](http://en.cppreference.com/w/cpp/container/map)有两个以上的模板参数。你还有一个'比较'类型和'Allocator'类型。你必须指定所有的,甚至是默认的。 –
请注意,您的代码将正常工作来C++ 17;以下解决方案都适用于C++ 14及更低版本。 –