我正在尝试使用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;。问题是代码不会编译,除非我包含重载运算符的定义&lt;&lt;与namespace std
。我认为这是由于C ++的名称查找机制,我仍然难以理解。即使我像这样定义非模板版本:
ostream& operator<<(ostream& os, const pair<int,int>& p) {
return os << p.first << "\t" << p.second << endl;
}
它仍然无法编译。任何人都可以解释原因吗?
答案 0 :(得分:2)
问题在于argument-dependent name lookup(ADL)。编译器正在operator<<
中搜索namespace std
的实现,因为ostream
和pair
都在该命名空间中。您应该创建一个从正确的命名空间转发到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
按引用而不是按值存储,因此您不能再依赖从pair<const int, int>
到pair<int, int>
的隐式转换。您可以将ostreamer
更改为按值存储,但实际上,它没有开销,我认为最好还是明确的。