Zsolt Diveki
Zsolt Diveki

Reputation: 159

Overloading fstream << operator to save "any" kind of data

I have created a Test class that has a public variable double x. I have overloaded the ostream << operater to be able to print out the variable x. I have also written an external save(filename, object) function that would save the content of the object in a particular way. I would like to use the << operator to save the content of x into a file. Header file (TestH.hpp) looks like this:

#ifndef TESTH_HPP_
#define TESTH_HPP_

#include <iostream>
#include <fstream>
#include <string>


class Test {
public:
    double x;
friend std::ostream& operator << (std::ostream& os, Test& p);
inline Test();
inline virtual ~Test();
};

inline std::ostream& operator << (std::ostream& os, Test& p);
template <class V>
inline void save(const std::string& pname, const V& data);

#endif /* TESTH_HPP_ */

This is the file for defining the functions (TestC.cpp):

#ifndef TESTC_CPP_
#define TESTC_CPP_

#include "TestH.hpp"

Test::Test() {
    x=10;
}

Test::~Test() {}

std::ostream& operator << (std::ostream& os, Test& p) {
 // Output to screen
    os << "Test:\t";
    os << p.x;
    return os;
}

template <class V>
void save(const std::string& pname, const V& data) {
    std::ofstream myfile;
    myfile.open(pname.c_str());
    myfile << data;
    myfile.close();
    std::cout << "====== File is saved! ======\nPathname: " << pname << std::endl;
}

#endif /* TESTC_CPP_ */

And finally here is the code to test the save function (Test.cpp):

#include <iostream>
#include "TestC.cpp"

int main () {
    std::string fn = "test.txt";
    int i=1;
    Test a;

//  std::cout << a;
    save(fn,a);
    return 0;
}

I get a really long list of errors, but basically it sais that in the TestC.cpp code the compiler cannot do the myfile << data; command:

In file included from ../Test.cpp:3:0:
../TestC.cpp:33:9: note:   ‘const Test’ is not derived from ‘const std::basic_string<_CharT, _Traits, _Alloc>’
  myfile << data;

Could you please help me resolving this issue. Thank you for your time.

Upvotes: 0

Views: 2015

Answers (2)

marom
marom

Reputation: 5230

You get the error because you are trying to save a const object and you have overloaded the operator for non const case.

Turn

std::ostream& operator << (std::ostream& os, Test& p) {

into

std::ostream& operator << (std::ostream& os, const Test& p) {

Upvotes: 0

Barry
Barry

Reputation: 303377

You are streaming Test by non-const reference:

friend std::ostream& operator << (std::ostream& os, Test& p);

You want to stream it by const reference:

friend std::ostream& operator << (std::ostream& os, const Test& p);
                                                    ^^^^^^

The error comes from the fact that when you call it from save(), you are passing in a const reference:

template <class V>
void save(const std::string& pname, const V& data) {
    ...
    myfile << data; // <== data is const Test&
    ...
}

Upvotes: 3

Related Questions