用于接收通用映射作为参数的模板函数

时间:2017-08-09 21:48:29

标签: c++ c++11 templates stdmap template-templates

在许多情况下,我们希望在完全相同的std::mapstd::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中读到了模板模板的使用。这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:5)

如果您以这种方式定义,编译器无法推断模板参数。 尝试使用:

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, "!");

答案 1 :(得分:4)

尝试

std::map

代码中的(更大)问题是std::unordered_mapstd::map是具有四个(而不是两个)模板参数的模板类。第3个和第4个具有默认值,因此您可以将 std::map<int, long> map1; 对象定义为

 std::map<int, long, std::less<int>,
          std::allocator<std::pair<const int, long> >> map1;

但是,使用默认参数,您可以将其定义为

auto

(ps:或者你可以简单地使用var favoriteWords = Favorites.SelectMany(i => i.Split(' ')); ,就像在Semyon Burov的解决方案中一样; +1)

答案 2 :(得分:0)

试试这个:

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;
}