重载运算符时编译错误<<使用模板参数

Compile error when overloading operator<< with template arguments

本文关键字:lt 参数 运算符 错误 重载 编译      更新时间:2023-10-16

我正在尝试使用stl-copy()来打印映射中的键值对。代码如下:

#include <iterator>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
//compile error if I comment out "namespace std"
namespace std {    
template<typename F, typename S> 
ostream& operator<<(ostream& os, const pair<F,S>& p) {
  return os << p.first << "t" << p.second << endl;
}
}
int main() {
  map<int, int> m;
  fill_n(inserter(m, m.begin()), 10, make_pair(90,120));
  copy(m.begin(), m.end(), ostream_iterator<pair<int,int> >(cout,"n"));
} 

我正试图使运算符<lt;。问题是,除非我围绕重载运算符<lt;用CCD_ 1。我认为这是由于C++的名称查找机制,我仍然难以理解。即使我定义这样的非模板版本:

ostream& operator<<(ostream& os, const pair<int,int>& p) {
    return os << p.first << "t" << p.second << endl;
}

它仍然无法编译。有人能解释一下原因吗?

您的问题是与参数相关的名称查找(ADL)。编译器正在namespace std中搜索operator<<的实现,因为ostreampair都在该命名空间中。您应该制作一个包装器,从正确的名称空间转发到operator<<

template<class T>
struct ostreamer {
  ostreamer(const T& value) : reference(value) {}
  const T& reference;
  friend ostream& operator<<(ostream& stream, const ostreamer& value) {
    return stream << value.reference;
  }
};

然后只使用ostream_iterator<ostreamer<pair<const int, int>>>而不是ostream_iterator<pair<int, int>>。请注意,由于ostreamer是通过引用而不是通过值存储的,因此不能再依赖于从namespace std0到pair<int, int>的隐式转换。您可以将ostreamer更改为按值存储,但实际上,它没有开销,而且我认为最好是显式的。