【问题标题】:How can I use my own abc::endl; here like in iostream如何使用我自己的 abc::endl;就像在 iostream 中一样
【发布时间】:2013-09-27 14:41:27
【问题描述】:

当我尝试自己的版本时,我得到了

错误 C2039:“endl”:不是“abc”的成员 错误 C2065: 'endl' : 未声明的标识符

这是下面的代码。

#include <iostream>
#include <stdio.h>

//assume this class uses some proprietary logging system.  I just use the wrap the C
//output functions here but assume is a corporate log system
namespace abc {

   class log_stream
   {
   public:
      log_stream(const char* filename) {
         fp_ = fopen(filename, "w");
      }

      log_stream& operator<<(short val)          { if (fp_) { output_int(val); } return *this; }
      log_stream& operator<<(unsigned short val) { if (fp_) { output_int(val); } return *this; }
      log_stream& operator<<(int val)            { if (fp_) { output_int(val); } return *this; }
      log_stream& operator<<(unsigned int val)   { if (fp_) { output_int(val); } return *this; }
      log_stream& operator<<(long val)           { if (fp_) { output_int(val); } return *this; }
      log_stream& operator<<(unsigned long val)  { if (fp_) { output_int(val); } return *this; }
      log_stream& operator<<(const char* val)    { if (fp_) { output_string(val); } return *this; }
      inline log_stream& endl(log_stream& os)  { return os.endl(); }
      //etc
      log_stream& endl() {
         if(fp_)
            fputc('\n', fp_);
         return *this;
      }

   private:
      void output_int(long v) { fprintf(fp_, "%d", v); }
      void output_string(const char* s) { fprintf(fp_, "%s", s); }
      FILE* fp_;
   };
}  //namespace abc

int main() {
   abc::log_stream logger("myfile.txt");
   //error C2039: 'endl' : is not a member of 'abc', error C2065: 'endl' : undeclared identifier
   logger << "number " << 3 << abc::endl;
   return 0;
}

更新:

如果我添加

inline log_stream& endl(log_stream& os)  { return os.endl(); }

在 abc 命名空间内(但在类之外,然后我得到 ​​p>

error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'abc::log_stream' (or there is no acceptable conversion)

哪个更接近(我认为)解决,但还没有。

更新2。

嗯,那是毛茸茸的!这是我为任何做类似事情的人解决问题的方法。谢谢朱利安。

将这些添加到类中:

  ~log_stream() { if(fp_) fclose(fp_); }

  // this is the main one I was missing
  abc::log_stream& abc::log_stream::operator<<( log_stream& (*pf)(log_stream&) )
  {
     return pf(*this);
  }

然后课外:

abc::log_stream& endl(abc::log_stream& 日志) { 日志.endl(); 返回日志; }

【问题讨论】:

  • 我在log_stream 类中看到了一个endl 成员函数。我在 abc 命名空间中没有看到声明为顶级的 endl 实体。我错过了什么吗?
  • 有点跑题了——你真的想要一个有自己实现的日志流吗?看看marcoarena.wordpress.com/2013/09/13/…
  • 更新后:现在看看约翰的回答。

标签: c++ iostream


【解决方案1】:

std::endl 是一个以std::ostream 作为其单个参数的函数,ostream&lt;&lt; 是一个采用std::endl 类型的重载。

要为您的 log_stream 复制此行为,请为其覆盖 std::endl

abc::log_stream& std::endl( abc::log_stream& log )
{
    log.endl();
    return log;
}

并覆盖abc::log_stream::operator&lt;&lt; 以使用它:

abc::log_stream& abc::log_stream::operator<<( log_stream& (*pf)(log_stream&) )
{
    return pf(*this);
}

如您所见,abc::log_stream::operator&lt;&lt; 的参数将std::endl 的类型作为参数。

另外,请注意 std::endl flushes the stream。因此,您应该考虑在abc::log::endl() 中调用fflush(fp_)

【讨论】:

  • 太棒了,谢谢。我确实开始实施 operator
【解决方案2】:

我认为你应该创建一个 operator&lt;&lt; 来接受你的 endl 类型。或者让它采取std::endl。另请参阅类似问题的答案:https://stackoverflow.com/a/1134467/4323 - 基本上,endl 是一个像你一样的函数,但你需要为你的类创建一个插入运算符,接受该函数作为其右手参数,并调用它.

【讨论】:

    猜你喜欢
    • 2020-12-12
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多