Ошибка при попытке сохранить содержимое файла с помощью ostream

#c #operator-overloading #fstream #cout #ostream

#c #перегрузка оператора #fstream #cout #ostream

Вопрос:

Я написал программу на C и скомпилировал ее с помощью gcc 7.3. Это простая программа, которая записывает строку в файл. Но ошибка компилятора генерируется только при компиляции с использованием gcc 7.3. Используя старый компилятор 4.8.5, программа успешно компилируется.

Ошибка компилятора заключается в следующем

В функции-члене ‘void CDemoMap::SaveFile(std::__cxx11::stringamp;)’: ..srcVerifyProgram.cpp:51:9: ошибка: нет соответствия для ‘operator<<‘ (типы операндов ‘std::ostream {он же std::basic_ostream}’ и ‘std ::ostream {он же std::basic_ostream} ‘) cout << печать (coutFile)

Кто-нибудь может помочь мне решить эту проблему? Код следующий

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

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


std::ostreamamp; operator << (ostreamamp; s, const CDemoMap amp;m)
{
   if (m.m_sMap.size())
   {
      s << "-----------------nSOCKET FQDN MAPn-----------------n";
      s << "fqdn                    host:port              timestampn";

      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::ostreamamp; CDemoMap::print(std::ostream  amp;s)
{
   return s << (*this);
}

void CDemoMap::saveFile(std::string amp; 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;
}
  

Комментарии:

1. Кажется, что конфигурация ostream amp; ожидает файл, когда вы используете опцию печати

2. Почему это компилируется в компиляторе 4.8.5? компилятор 4.8.5 не поддерживает C 11 по сравнению с 7.3.1. Что было изменено в операторе ostream в последнем стандарте?

Ответ №1:

В разделе 4.8.5 следующая строка:

  cout << print(coutFile);
  

преобразуется в:

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

потому что до C 11 был оператор, преобразующий ostream в void* , чтобы проверить, нет ли в stream ошибок из ссылки:

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

1) Возвращает нулевой указатель, если fail() возвращает true, в противном случае возвращает
ненулевой указатель. Этот указатель неявно преобразуется в bool и
может использоваться в логических контекстах.

2) Возвращает true, если поток не содержит ошибок и готов к операциям ввода-вывода. В частности, возвращает !fail().

Начиная с C 11, код не может компилироваться, поскольку преобразование в void * отключено.

Почему вы хотите передать возвращаемый тип print — ostream другому ostream? Это просто должно быть:

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