std :: ostream_iterator找不到运算符<<

时间:2013-11-29 11:12:07

标签: c++ iterator operators operator-overloading

我已为operator<<声明了std::pair<int, int>

std::ostream& operator<<(std::ostream& o, const std::pair<int, int>& p) {
    o << p.first << p.second;
    return o;
}

我想在打印数据时使用此运算符:

std::vector<std::pair<int, int>> data;
std::copy(data.begin(), data.end(), std::ostream_iterator<std::pair<int, int>>(std::cout, "\n"));

但是编译器说,no match for operator<< ...... 我做错了什么?

4 个答案:

答案 0 :(得分:9)

std::copy无法在operator <<命名空间中找到std::pair的{​​{1}}重载。没有好办法,在std命名空间的算法中从operator <<命名空间重载std对象。

您可以将std与仿函数一起使用,这将打印您的值,例如使用lambda。

std::for_each

你不能在std命名空间中加载重载,你只能为用户定义的类型添加特殊化,因为

如果它向名称空间std或a添加声明或定义,则C ++程序的行为是未定义的 命名空间std中的命名空间,除非另有说明

程序可能会添加模板专业化 对于任何标准库模板到命名空间std,仅当声明取决于用户定义的类型时 并且专业化符合原始模板的标准库要求,并未明确说明 禁止。

答案 1 :(得分:3)

也许你可以试试this

struct PAIR : std::pair<int, int>
{
  using std::pair<int, int>::pair;
};

int main(int argc, char* argv[]) {
std::vector<std::pair<int, int>> data;
std::copy(data.begin(), data.end(), std::ostream_iterator<PAIR>(std::cout, "\n"));
    return 0;
}

由于已经有了一个很好的答案,我只想引用链接:

  

问题是名称查找找不到你的   运算符&lt;&lt;(ostream&amp; os,const PAIR&amp; r)。试图调用的代码   运算符&lt;&lt;是在ostream_iterator内的某个地方&lt;&gt;是的   本身在std命名空间内。名称查找环顾四周   ostream_iterator内的正确功能&lt;&gt;和std命名空间;该   参数依赖查找在这里没有帮助,因为两者都有   参数也在std命名空间中。

     

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


用法:

#include <iostream>
#include <limits>
#include <vector>
#include <iterator>
#include <map>

std::ostream& operator<<(std::ostream& o, const std::pair<int, int>& p) {
    o << p.first << p.second;
    return o;
}

struct PAIR : std::pair<int, int>
{
    using std::pair<int, int>::pair;
};

int main(int argc, char* argv[]) {
std::vector<std::pair<int, int> > data;
data.push_back(std::pair<int, int>(50, 42));
std::copy(data.begin(), data.end(), std::ostream_iterator<PAIR>(std::cout, "\n"));
    return 0;
}

答案 2 :(得分:1)

Google搜索结果的一般情况会让您了解具体案例......

请注意,如果您在名称节奏N中使用类型T,要使用ostream_iterator +副本组合,您的运算符&lt;&lt;对于T,需要在名称空间N中,而不是在::。

namespace N {
    class T;
    std::ostream & operator << ( std::ostream &; T const & );
}

在这种情况下,std :: copy可以找到你的define N :: operator&lt;&lt;(std :: ostream&amp ;; T const&amp;)

使用运营商时,您不必担心符合条件的访问权限。

N::T t;
std::cout << t << std::endl;

std::list<N::t> alist;
alist.push_back(t);

std::ostream_iterator<N::t> out_itr(std::cout, "\n");
std::copy(alist.begin(), alist.end(), out_itr);

答案 3 :(得分:0)

std::vector<std::pair<int, int> > data;
std::copy(data.begin(), data.end(), std::ostream_iterator<std::pair<int, int> >(std::cout, "\n"));

请尝试这个,我认为>之间有空格。