0

I'm trying to print an object Order (actually a vector of Orders). Order has some data members, including a vector with other objects, Purchase.

I can print the vector<Purchase> to cout on its own, and I can print vector<Objects> if I ignore the vector<Purchase> member. But the tricky part is to print vector<Objects> with vector<Purchase> included.

Here is my code:

#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#include <sstream>

using namespace std;

struct Purchase {
    string name;
    double unit_price;
    int count;
};

struct Order {
    string name;
    string adress;
    double data;
    vector<Purchase> vp;
};

template<typename Iter>   //this is my general print-vector function
ostream& print(Iter it1, Iter it2, ostream& os, string s) {
    while (it1 != it2) {
        os << *it1 << s;
        ++it1;
    }
    return os << "\n";
}

ostream& operator<<(ostream& os, Purchase p) {
    return os << "(" << p.name << ", " << p.unit_price << ", " << p.count << ")";
}

ostream& operator<<(ostream& os, Order o) {
    vector<Purchase> vpo = o.vp;
    ostringstream oss;
    oss << print(vpo.begin(), vpo.end(), oss, ", "); //This is what I would like to do, but the compiler doesn't like this conversion (from ostream& to ostringstream)

    os << o.name << "\n" << o.adress << "\n" << o.data << "\n"
        << oss << "\n";
    return os;
}

int main() {
    ifstream infile("infile.txt");
    vector<Order> vo;
    read_order(infile, vo);  //a function that reads a txt-file into my vector vo
    print(vo.begin(), vo.end(), cout, "");
    return 0;
}

As you can see, I had the idea to use ostringstreams as a temporary variable, that I would store the vector<Purchase> before I pass it on to the ostream& os. But this is a no go. What would be a good solution to this problem?

I am fairly new to C++ and are just learning the different uses of streams, so please bear with me if this is a stupid question.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
JEB
  • 5
  • 1

2 Answers2

2

Looks like you have two minor typos.

First, remove the indicated portion:

   oss << print(vpo.begin(), vpo.end(), oss, ", ")
// ↑↑↑↑↑↑↑

Then, later in that same function, you cannot stream a stringstream, but you can stream the string serving as its underlying buffer, so use std::stringstream::str():

os << o.name << "\n" << o.adress << "\n" << o.data << "\n"
    << oss.str() << "\n";
//        ↑↑↑↑↑↑

With those fixes in place, and the missing read_order function abstracted away, your program compiles.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
-2

The easiest way is to write an overload of operator<< that takes a const reference to a std::vector<Purchase> and then just stream the vector into the ostream:

std::ostream& operator<<(std::ostream& os, const std::vector<Purchase>& v);
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • 2
    That's pretty much what he's doing. Suggesting a minor top-level design change does nothing to explain what's wrong with the shown code. – Lightness Races in Orbit Oct 19 '15 at 11:26
  • 1
    "top level design change" in a 20-line program. Hilarous. Are you bored LRiO? – Richard Hodges Oct 19 '15 at 11:28
  • 1
    Put down your personal attacks for a minute (wow they seem to be in vogue today - full moon?) and explain to me how your answer, which does nothing but suggest changing `ostream& print(Iter it1, Iter it2, ostream& os, string s)` into `std::ostream& operator<<(std::ostream& os, const std::vector& v)`, is helpful in any way? – Lightness Races in Orbit Oct 19 '15 at 11:29
  • It seems to me that the OP is not aware that he can overload `operator<<` for vectors. Realising that he can do so will allow him to write clear, succinct code since he is already aware of how to write an `operator<<` for a user-defined object. – Richard Hodges Oct 19 '15 at 11:31
  • Read my answer to discover the _actual_ cause of the problem. – Lightness Races in Orbit Oct 19 '15 at 11:34
  • I see you're characteristically pugnacious today LRiO. I am aware of the return type problem, and the trailing separator problem, and the fact that the `operator<<` functions are taking copies. Sorry to offend you honey, but it's easily done. – Richard Hodges Oct 19 '15 at 11:37
  • Okay _now_ I'm bored. Act your age for a change, Richard, for goodness's sake. – Lightness Races in Orbit Oct 19 '15 at 11:37
  • 1
    Thank you, both of you! No need to fight, both of your answers were useful to me. LRiO answered my specific question, but RH design suggestion indeed made my program clearer and more straight forward, plus also solved the overlaying problem, which was to print out my vector of Order's. – JEB Oct 19 '15 at 13:54