std::pair<K,V> 未调用模板化函数 模板重载不起作用

std::pair<K,V> templated function not called template overloading not working

模板重载在当前情况下不起作用。

我有一个重载模板程序和一个包含映射、对和向量的复杂数据结构。 std::pair 未调用重载的模板函数。 我无法弄清楚它的原因。它正在调用 #1 通用模板函数。

#include <iostream>
#include <vector>
#include <map>
#include <utility>
template <typename T>
bool f(T& x) // #1
{
    std::cout << "body of f\n";
    return f(x);
}

template <typename T>
bool f(std::vector<T>& v) // #2
{
    std::cout << "body of f for vectors\n";
    return true;
}

template <typename Key, typename Value>
bool f(std::pair<Key,Value>& v) // #3
{
    std::cout << "body of f for pairs\n";
    for(auto& e: v) {
      f(e.first);
    }
    for(auto& e: v) {
      f(e.second);
    }
    return true;
}

template <typename Key, typename Value>
bool f(std::map<Key,Value>& v) // #4
{
    std::cout << "body of f for maps\n";
    for(auto& e: v) {
      f(e.first);  // expecting this call goes to #3
    }
    for(auto& e: v) {
      f(e.second);
    }
    return true;
}

int main() {
  std::vector<int> v{1,2};
  std::map<std::pair<int,int>,std::vector<int>> m_map = {
                                            {{10,20}, {5,6}},
                                            {{11,22}, {7,8}}
                                        };
    f(m_map); // this call goes to #4
}

控制台输出为

body of f for maps
body of f
body of f
body of f
body of f
body of f .... Goes on infinitely

请告诉我这段代码有什么问题。

谢谢。

map 的迭代是在 std::pair<const Key, value> 上完成的,因此

std::map<std::pair<int,int>,std::vector<int>> m_map;

你会打电话给

f(const std::pair<int,int>&)

只匹配#1。

由于您不修改任何元素,我建议将 const 添加到每个输入引用中。

首先,您的 m_map 类型 std::map<std::pair<int,int>,std::vector<int>> 具有值类型 std::pair<const std::pair<int,int>, std::vector<int>>。因此,在#4中,estd::pair<const std::pair<int,int>, std::vector<int>>&类型,e.firstconst std::pair<int,int>类型。

f(e.first) 不会调用 #3,因为您不能将非 const 左值引用绑定到 const 对象。如果将其参数从 std::pair<Key,Value>& v 更改为 const std::pair<Key,Value>& v,它将起作用。但是,它最终会出现编译错误,因为您不能在一对上使用基于范围的 for 循环进行迭代。变化

for(auto& e: v) {
  f(e.first);
}
for(auto& e: v) {
  f(e.second);
}

f(e.first);
f(e.second);

#3 中。

最后,您错过了 int 的最终重载以停止无限递归。添加内容为:

bool f(int i) {
  std::cout << "body of f for ints\n";
  return true; 
}

工作live demo