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
中,e
是std::pair<const std::pair<int,int>, std::vector<int>>&
类型,e.first
是const 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。
模板重载在当前情况下不起作用。
我有一个重载模板程序和一个包含映射、对和向量的复杂数据结构。 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
中,e
是std::pair<const std::pair<int,int>, std::vector<int>>&
类型,e.first
是const 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。