繁体   English   中英

为什么ostream_iterator不能按预期工作?

[英]Why does ostream_iterator not work as expected?

不用说以下代码:

#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)); 
}

这是一个常见问题: std::ostream_iterator在实例化std::ostream_iterator时,看不到operator<<

在实例化期间,名称查找尝试在命名空间std查找operator<< 将找到候选者,因此不会考虑其他名称空间(特别是,不考虑全局名称空间)。 然后,重载决策起作用:没有任何重载与参数类型匹配,因此编译失败。 请注意,参数依赖查找在这里没有任何帮助,因为std::pair也在命名空间std

你有两个解决方案:

  • 将您的operator<<封闭在namespace std { } ,尽管根据标准 (17.4.3.1)您应该知道这是非法的
  • 避免使用std::copy执行此任务并使用std::for_each (使用'老式' std::copy函数或lambda)

问题是名称查找找不到你的operator<<(ostream& os, const PAIR& r) 尝试调用operator<<的代码位于ostream_iterator<>内部的某个位置,该位置本身位于std命名空间内。 名称查找在ostream_iterator<>std名称空间内查找正确的函数; 参数依赖查找在这里没有帮助,因为这两个参数也在std命名空间中。

所以,我的建议是(1)要么将你的运算符包装到namespace std { } ,那就是UB,IIRC。 或者(2)创建一个继承自std::pair的结构,以在命名空间中定义一个新类型,并使用ADL查找operator<<()

更新:

我的第三个建议是使用自定义操纵器打印出这对。

至于我的第二个建议,如果你可以使用C ++ 11,继承std::pair应该很容易(未经测试):

struct PAIR : std::pair
{
  using std::pair::pair;
};

如果您不能使用C ++ 11,那么我建议使用自定义操纵器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM