为什么 ostream_iterator 不能按预期工作?
以下代码不用多说:
#include <utility>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
typedef pair<char, char> PAIR;
ostream& operator <<(ostream& os, const PAIR& r)
{
return os << r.first;
}
int main()
{
vector<PAIR> coll;
cout << coll[0]; // OK.
// The following line will cause a compilation error! Why???
copy(coll.begin(), coll.end(), ostream_iterator<PAIR>(cout));
}
推荐答案
问题是名称查找没有找到你的operator<<(ostream& os, const PAIR& r)
.尝试调用 operator<<
的代码位于 ostream_iterator<>
内的某处,它本身位于 std
命名空间内.名称查找在 ostream_iterator<>
和 std
命名空间中寻找正确的函数;参数相关查找在这里没有帮助,因为这两个参数也都在 std
命名空间中.
The problem is that the name lookup does not find your operator<<(ostream& os, const PAIR& r)
. The code that tries to invoke the operator<<
is in somewhere inside the ostream_iterator<>
which is itself inside the std
namespace. The name lookup looks around for the right function inside ostream_iterator<>
and the std
namespace; the argument dependent lookup does not help here because both of the parameters are in the std
namespace, too.
所以,我的建议是 (1) 要么将您的运算符包装到 namespace std { }
中,但那是 UB、IIRC.或者 (2) 创建一个继承自 std::pair
的结构体以在您的命名空间中定义一个新类型,并使用 ADL 查找您的 operator<<()
.
So, my suggestion is (1) either to wrap your operator into namespace std { }
, but that is UB, IIRC. Or (2) create a struct inheriting from std::pair
to define a new type in your namespace, and using the ADL to find your operator<<()
.
更新:
我的第三个建议是使用自定义操纵器打印出该对.
My 3rd suggestion is to use a custom manipulator to print out the pair.
至于我的第二个建议,如果您可以使用 C++11,那么从 std::pair
继承应该很容易(未经测试):
As for my 2nd suggestion, if you can use C++11, inheriting from std::pair
should be easy (untested):
struct PAIR : std::pair
{
using std::pair::pair;
};
如果您不能使用 C++11,那么我建议您使用自定义操纵器.
If you cannot use C++11, then I suggest using a custom manipulator.
相关文章