Search code examples
c++operator-overloadingfstreamcoutostream

Error when try to save the content of a file using ostream


I wrote a program in C++ and compile this using gcc 7.3. This a simple program that writes a string in a file. But a compiler error is generated only when compiles using the gcc 7.3. Using an old compiler 4.8.5 the program is succesfully compiled.

The compiler error is the following

In member function 'void CDemoMap::saveFile(std::__cxx11::string&)': ..\src\VerifyProgram.cpp:51:9: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream}' and 'std::ostream {aka std::basic_ostream}') cout << print(coutFile)

Is anyone who can help me to solve this issue? The code is the following

#include <map>
#include <iostream>
#include <ostream> 

#include <fstream>
using namespace std;
class CDemoMap
{
    public:
     map<int,int> m_sMap;
    void saveFile(std::string &);
    std::ostream& print(std::ostream  &s);
};


std::ostream& operator << (ostream& s, const CDemoMap &m)
{
   if (m.m_sMap.size())
   {
      s << "-----------------\nSOCKET FQDN MAP\n-----------------\n";
      s << "fqdn                    host:port              timestamp\n";

      for (map<int,int>::const_iterator iter = m.m_sMap.cbegin(); iter != 
           m.m_sMap.cend(); ++iter)
      {
         s << iter->first << "   " << (iter->second);
      }
      s << endl;
   }
   return s;
}
std::ostream& CDemoMap::print(std::ostream  &s)
{
   return s << (*this);
}

void CDemoMap::saveFile(std::string & test)
{
   char outFile[50];
   snprintf(outFile, sizeof(outFile), "Data:%s", test.c_str());

   std::ofstream coutFile;

   coutFile.open("Test.txt", std::ios::app);

   cout << print(coutFile);

   coutFile.close();
}


int main() {
    CDemoMap cSocket;
    string str = "Hello";
    cSocket.saveFile(str);
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    return 0;
}

Solution

  • Under 4.8.5 the following line:

     cout << print(coutFile);
    

    is translated into:

     void* v =  print(coutFile);
     std::cout << v;
    

    because before C++11 there was operator converting ostream to void* to check if stream has no errors from reference:

    operator void*() const;
    (1)   (until C++11)
    explicit operator bool() const;
    (2)   (since C++11)
    Checks whether the stream has no errors.
    

    1) Returns a null pointer if fail() returns true, otherwise returns a non-null pointer. This pointer is implicitly convertible to bool and may be used in boolean contexts.

    2) Returns true if the stream has no errors and is ready for I/O operations. Specifically, returns !fail().

    Since C++11 the code cannot compile because conversion to void* is disabled.

    Why do you want to pass return type of print - ostream to another ostream? It just should be:

    print(coutFile); // there is no need to pass ostream to cout