首页 > 解决方案 > 尝试使用 ostream 保存文件内容时出错

问题描述

我用 C++ 编写了一个程序并使用 gcc 7.3 编译它。这是一个在文件中写入字符串的简单程序。但是只有在使用 gcc 7.3 编译时才会产生编译器错误。使用旧的编译器 4.8.5 成功编译程序。

编译器错误如下

在成员函数 'void CDemoMap::saveFile(std::__cxx11::string&)': ..\src\VerifyProgram.cpp:51:9: error: no match for 'operator<<' (操作数类型是 'std: :ostream {aka std::basic_ostream}' 和 'std::ostream {aka std::basic_ostream}') cout << print(coutFile)

有谁能帮我解决这个问题吗?代码如下

#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;
}

标签: c++operator-overloadingfstreamcoutostream

解决方案


在 4.8.5 下,以下行:

 cout << print(coutFile);

被翻译成:

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

因为在 C++11 之前,有运算符将 ostream 转换为void*以检查流是否没有来自引用的错误:

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) 如果流没有错误并且准备好进行 I/O 操作,则返回 true。具体来说,返回 !fail()。

由于 C++11 代码无法编译,因为转换为 void* 被禁用。

为什么要将返回类型的 print - ostream 传递给另一个 ostream?它应该是:

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

推荐阅读