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

std::ostream_iterator does not find operator<<

本文关键字:lt 运算符 iterator ostream std 找不到      更新时间:2023-10-16

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

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<<。。。我做错了什么?

std::copystd命名空间中找不到operator <<std::pair的重载。在来自std命名空间的算法中,没有好的方法可以为来自std命名空间的对象重载operator <<

您可以将std::for_each与functor一起使用,后者将打印您的值,例如与lambda一起使用。

std::for_each(data.begin(), data.end(), [](const std::pair<int, int>& p)
{
   std::cout << p << std::endl;
});

您不能在std命名空间中放置重载,您只能为自以来的用户定义类型添加专门化

如果C++程序将声明或定义添加到命名空间std或命名空间std中的命名空间,除非另有指定

程序可以添加模板专用化对于任何标准库模板,仅当声明依赖于用户定义的类型时,才将其命名为std并且专业化满足原始模板的标准库要求,并且没有明确禁止。

也许你可以试试这个:

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;(ostream&os,const PAIR&r)。尝试调用的代码运算符<lt;在ostream_iterator<>内的某个位置哪个是自身位于std命名空间内。名称查找查找ostream_iterator<>内的右函数以及std命名空间;这个依赖于参数的查找在这里没有帮助,因为参数也在std命名空间中。

因此,我的建议是(1)要么将运算符封装到命名空间中std{},但这是UB,IIRC。或者(2)创建继承自的结构std::pair在命名空间中定义一个新类型,并使用ADL找到您的运营商<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;
}

那些使用谷歌搜索的人的一般情况会让你了解具体情况。。。

请注意,如果您在名称空间N中有一个类型T,要使用ostream_iterator+副本组合,您的运算符<lt;因为T需要在名称空间N中,而不是在:中。

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

在这种情况下,std::copy可以找到您定义的N::operator<lt;(std::ostream&T const&)

在使用运算符时,您不必担心是否符合访问资格。

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);
std::vector<std::pair<int, int> > data;
std::copy(data.begin(), data.end(), std::ostream_iterator<std::pair<int, int> >(std::cout, "n"));

请试试这个,我想>之间有空位。