已经重载了<<和>>符号,使用流迭代器,只有>>有效,<<报错

istream& operator >>(istream &input, sales_data &s){
    input >> s.bookno >> s.units_sold >> s.price;
    if(input){
        s.revenue = s.units_sold * s.price;
    }
    return input;
}

ostream& operator << (ostream &output,sales_data &s){
    output << s.bookno <<" "<< s.units_sold << " "<<s.revenue<<" "<<s.avg_price()<<endl;
    return output;
}

单独使用cin和cout都没有问题,就是流迭代器使用的时候有问题

istream_iterator<sales_data> item_iter(cin),eof;
    ostream_iterator<sales_data> out_iter(cout," ");
    sales_data sum = *item_iter++;
    while(item_iter!=eof){
        if(sum.isbn()==item_iter->isbn()){
            sum += *item_iter++; 
        }
        else{
            out_iter = sum;//出问题地方
            sum += *item_iter++; 
        }
    }
    out_iter = sum;//出问题地方

 

很明显就是 const 问题。

ostream& operator << (ostream &output, const sales_data &s)

参照错误提示及函数原型:

ostream_iterator& operator=( const T& value );

即 ostream_iterator 只接受常量引用,将 value 再次传递给 ostream::<< 时出错,因为要求是非常量引用。

const 修饰后错误很可能转移到 avg_price() 函数上,因为你没有将其定义为 const 函数。请仔细阅读错误提示,一字一字地读。

真诚建议:创建完整代码 repo,方便坛友们了解所有细节,解决问题后直接提交 pr 给你。

针对你的代码,额外讲几个问题。

1. 不要用 using namespace std。或者来讲,尽可能都不要去用 using namespace。名字空间本身就是为了避免冲突而设计的。为图省事,把整个名字空间都暴露出来,很容易留坑。

2. 就算要用 using namespace,也一定不要在 header 文件里用。因为 header 会被 #include 很多次,这样会污染很多编译单元。

3. 代码格式还是要注意一下。建议装一个 clang-format 之类的工具,它能帮你自动格式化代码。

ostream& operator << (ostream &output,const sales_data &s)

您好,我是有问必答小助手,你的问题已经有小伙伴为您解答了问题,您看下是否解决了您的问题,可以追评进行沟通哦~

如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~

ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632

c++ - no match for ‘operator<<’ in ‘std::operator - Stack Overflow

no match for 'operator<<' (operand types are 'std::ostream' and 'double') : cpp_questions (reddit.com)

 

两个文章都建议用 friend: 

friend ostream& operator << (ostream& os, const mystruct& m)
  1. 修改下函数参数:friend ostream &operator<<(ostream &output, const sales_data &s);
  2. 使用的时候先解引用再赋值:*out_iter = sum;

更新:

  1. 如果你修改了还是不行,说明你的代码不只一处有问题,请贴完整代码。

class在声明的时候已经声明为友元函数了

    friend istream& operator >> (istream &,sales_data &);
    friend ostream& operator << (ostream &,sales_data &);

 

sales_data a{"123",1,3};
cout<<a<<endl;

也不会报错 直接就输出了

 

这个是测试用的代码  cin 和cout都没有问题

    istream_iterator<sales_data> item_iter(cin),eof;
    ostream_iterator<sales_data> out_iter(cout,"\n");
    ostream_iterator<int> test_out(cout," ");
    cout<<"start"<<endl;
    for(int i =0 ;i<10 ;i++)
        test_out = i;
    cout<<endl;
    // sales_data a;
    // cin>>a;
    // cout<<a<<endl;
    sales_data sum = *item_iter++;
    while(item_iter!=eof){
        if(sum.isbn()==item_iter->isbn()){
            // sum = sum + *item_iter;
            // item_iter++;//读取下一条记录
            sum += *item_iter++; 
        }
        else{
            *out_iter = sum;
            sum += *item_iter++; 
            // sum = *item_iter;
            // item_iter++;//读取下一条记录
        }
    }
    *out_iter = sum;

完整代码

//Sales_data.h

#ifndef SALA_DATA
#define SALA_DATA
#include<iostream>
#include<string>
using namespace std;
class sales_data
{
private:
    string bookno;//书号
    double units_sold;//销售的册数
    double price;
    double revenue;//总销售额
    double average;

public:
    // 无参构造函数
    sales_data();
    //sales_data() = deflaut 默认构造函数;
    //有参数的构造函数
    sales_data(string b,int u,double p):bookno(b),units_sold(u),price(p){};
    //运算符重载 友元函数,其他类调用该类中的私有数据,返回的是引用类型,必须保证是引用,否则调用构造函数,输入输出的对象不是一个,
    friend istream& operator >> (istream &,sales_data &);
    friend ostream& operator << (ostream &,sales_data &);
    friend sales_data operator + (sales_data &lhs,sales_data & rhs);
    //引用不会调用拷贝构造函数,在内存中不产生被返回值的副本
    sales_data& operator = (const sales_data &);
    friend bool operator == (sales_data &,sales_data &);
    sales_data &operator += (const sales_data &);
    double avg_price();
    //声明isbn函数,返回书籍号
    string isbn() const;
    
    //一个combine成员函数,用于将一个sales_data对象加到另一个对象上
    sales_data& combine(const sales_data &);
    //声明sales_data类的非成员接口函数
    //一个read函数,将数据从istream读入到sales_data对象中
    friend istream & read(istream &,sales_data &);
    //一个add函数,执行两个对象的加法
    //friend sales_data add(const sales_data &, const sales_data &);
    //sales_data add(const sales_data &, const sales_data &);
    friend ostream & print(ostream &,sales_data &);
};
sales_data add(const sales_data &, const sales_data &);
bool compareIsbn(const sales_data &,const sales_data&);
#endif


//Sala_data.cpp
#include"Sales_data.h"

// 加default 就不需要赋初始值
sales_data::sales_data(){
    bookno = "null";
    units_sold = 0;
    price = 0.0;
}
//接下来的四个函数都是友元函数,,其他类的,不需要加class的定义域
istream& operator >>(istream &input, sales_data &s){
    input >> s.bookno >> s.units_sold >> s.price;
    if(input){
        s.revenue = s.units_sold * s.price;
    }
    return input;
}

ostream& operator << (ostream &output,sales_data &s){
    output << s.bookno <<" "<< s.units_sold << " "<<s.revenue<<" "<<s.avg_price()<<endl;
    return output;
}
//返回的是函数内部的变量,需要是拷贝值
sales_data operator + (sales_data &lhs,sales_data &rhs){
    sales_data ret;
    ret.bookno = lhs.bookno;
    ret.units_sold = lhs.units_sold + rhs.units_sold;
    ret.avg_price();
    return ret;
}

bool operator == (sales_data &lhs,sales_data &rhs){
    return lhs.units_sold == rhs.units_sold && lhs.price == rhs.price;
}
//重载赋值运算符  本类中声明的函数
sales_data& sales_data::operator = (const sales_data &lhs){
    bookno = lhs.bookno;
    units_sold = lhs.units_sold;
    price = lhs.price;
    return *this;
}

sales_data& sales_data::operator += (const sales_data &rhs){
    units_sold += rhs.units_sold;
    revenue += rhs.revenue;
    return *this;
}

double sales_data::avg_price(){
    average = revenue / units_sold;
    return average;
}

string sales_data::isbn() const{
    return bookno;
}

bool compareIsbn(const sales_data &lhs,const sales_data &rhs){
    return lhs.isbn()<rhs.isbn();
}
//和重载的+一致,只要返回的不是该函数内部的都加引用
sales_data &sales_data::combine(const sales_data &rhs){
    units_sold += rhs.units_sold;
    revenue += rhs.revenue;
    return *this;
} 

istream & read(istream &input,sales_data &rhs){
    input >> rhs.bookno >> rhs.units_sold >> rhs.price;
    rhs.revenue = rhs.units_sold * rhs.price;
    return input;
}
ostream & print(ostream &output,sales_data &rhs){
    output << rhs.bookno<<" "<< rhs.units_sold<<" " << rhs.price << " "<<rhs.average;
    rhs.avg_price();
    output <<" "<< rhs.revenue ;
    return output;
}
sales_data add(const sales_data &lhs,const sales_data &rhs){
    sales_data sum = lhs;
    sum.combine(rhs);
    sum.avg_price();
    return sum;
}


//main.cpp
    istream_iterator<sales_data> item_iter(cin),eof;
    ostream_iterator<sales_data> out_iter(cout,"\n");
    ostream_iterator<int> test_out(cout," ");
    cout<<"start"<<endl;
    for(int i =0 ;i<10 ;i++)
        test_out = i;
    cout<<endl;
    // sales_data a;
    // cin>>a;
    // cout<<a<<endl;
    sales_data sum = *item_iter++;
    while(item_iter!=eof){
        if(sum.isbn()==item_iter->isbn()){
            // sum = sum + *item_iter;
            // item_iter++;//读取下一条记录
            sum += *item_iter++; 
        }
        else{
            *out_iter = sum;
            sum += *item_iter++; 
            // sum = *item_iter;
            // item_iter++;//读取下一条记录
        }
    }
    *out_iter = sum;

 

代码高亮太乱了。其他细节没有看,你的代码报错的原因,应该是输出运算符第二个参数要写成 const ref,你的是 non-const ref。我写了一个代码,你可以参考。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>

class Foo {
  friend std::istream& operator>>(std::istream& ins, Foo& f);
  friend std::ostream& operator<<(std::ostream& outs, const Foo& f);

 public:
  Foo() {}
  Foo(int f, int b) : foo{f}, bar{b} {}

 private:
  int foo{0};
  int bar{0};
};

std::istream& operator>>(std::istream& ins, Foo& f) {
  return ins >> f.foo >> f.bar;
}

std::ostream& operator<<(std::ostream& outs, const Foo& f) {
  return outs << ".foo: " << f.foo << "\t.bar: " << f.bar;
}

int main() {
  const char* input = "1 2\n4 8";
  std::istringstream iss(input);
  std::vector<Foo> foovec;
  std::copy(std::istream_iterator<Foo>(iss), std::istream_iterator<Foo>(), std::back_inserter(foovec));
  std::copy(foovec.begin(), foovec.end(), std::ostream_iterator<Foo>(std::cout, "\n"));
  return 0;
}

效果:

$ ./a.out
.foo: 1 .bar: 2
.foo: 4 .bar: 8