构造函数中的运算符<<重载

operator << overloading in a constructor

本文关键字:lt 重载 运算符 构造函数      更新时间:2023-10-16

我正在调试程序,我想从该模式进行打印:

 std::cout << firstVar << ", " << secondVar << ", " << thirdVar << endl ;

短,即,如果我们写代码:

,应该发生同样的事情。
shortPrint(std::cout) << firstVar << secondVar << thirdVar;

注意:变量数量没有限制,可以是1,也可以是20,因此也应该有效:

shortPrint(std::cout) << firstVar << secondVar << thirdVar << anotherVar << oneMoreVar;

有人告诉我,最容易做到的是创建称为"短印"的类。

任何人可以帮我弄清楚吗?

开始,我会说我只需要实现构造函数和操作员le&lt;&lt;超载,但我不确定在这种情况下如何做到这一点。

是的,创建一个具有适当过载操作员的shortPrint类。这样的东西:

class shortPrint {
  ostream &o;
public:
  shortPrint(ostream &o) : o(o) {}
  template <typename T> shortPrint &operator<<(const T &t) {
    o << t << ',';
    return *this;
  }
  // support for endl, which is not a value but a function (stream->stream)
  shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
    o << pf;
    return *this;
 }
};

应该(基本上)。

消除额外逗号的问题使用以下方式:

class shortPrint {
  class shortPrint2{
    shortPrint &s;
  public:
    shortPrint2(shortPrint &s) : s(s) {}
    template <typename T> shortPrint2 &operator<<(const T &t) {
      s.o << ',' << t ;
      return *this;
    }
    shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
      s.o << pf;
      return s;
    }
  };
  ostream &o;
  shortPrint2 s2;
public:
  shortPrint(ostream &o) : o(o), s2(*this) {}
  template <typename T> shortPrint2 &operator<<(const T &t) {
    o << t;
    return s2;
  }
  shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
    o << pf;
    return *this;
  }
};

您可以做以下操作:

class _ostream_wrap
{
public:
    template <class T>
    _ostream_wrap& operator << (const T & v)
    {
        m_ost << "[ " << v << " ]";
        return (*this);
    }
    explicit _ostream_wrap(std::ostream & ost)
        :m_ost(ost)
    {}
private:
    std::ostream&   m_ost;
};
template <class OSTREAM>
_ostream_wrap shortPrint(OSTREAM & o)
{
    return _ostream_wrap(o);
}
//...
shortPrint(std::cout) << 1 << 2;

但是,此实现将在RVALUE上不起作用:

//you can't do something like the following:
shortPrint(MyOstream(some_args)) << 1;

这是因为_ostream_wrap类保留对流的引用,对于需要进行副本的RVALUES情况。要制作副本,您需要有两个实现(这是最终版本):

template <class OSTREAM>
class _ostream_wrap
{
public:
    template <class T>
    _ostream_wrap<OSTREAM>& operator << (const T & v)
    {
        m_ost << "[ " << v << " ]";
        return (*this);
    }

public:
    //the constructor is harder to write so i decided 
    //that for this i will keep the member public
    OSTREAM     m_ost;
};
template <class OSTREAM>
_ostream_wrap<OSTREAM&> shortPrint(OSTREAM & o)
{
    _ostream_wrap<OSTREAM&> rvalue;
    rvalue.m_ost = o;
    return rvalue;
}
template <class OSTREAM>
_ostream_wrap<OSTREAM> shortPrint(const OSTREAM & o)
{
    _ostream_wrap<OSTREAM> rvalue;
    rvalue.m_ost = o;
    return rvalue;
}

这是具有非常基本功能的东西:

#include <iostream>
struct shortPrint {
    explicit shortPrint(std::ostream& os)
        : strm(&os), first(true) {}
    template<typename T>
    shortPrint& operator<<(T&& t)
    {
        if (first) {
            first = false;
        } else {
            *strm << ", ";
        }
        *strm << std::forward<T>(t);
        return *this;
    }
    shortPrint& operator<<( std::ostream& (*func)(std::ostream&) )
    {
        *strm << func;
        return *this;
    }
private:
    std::ostream* strm;
    bool first;
};
int main()
{
    int i = 3;
    shortPrint(std::cout) << "1" << 2 << i << std::endl;
    shortPrint(std::cout) << 4;
}

棘手的部分是使逗号正确打印。我选择在每个流对象之前都打印它们,除非第一个对象。如您所见,只有一个通用的operator<<模板可以简单地打印逗号并转发参数。下一个问题是流动机,因为我们不想在他们面前打印逗号。其他operator<<过载可以解决此问题。如果您想更通用,还有两个需要照顾(请参见第9号)。

希望会有所帮助。

从函数返回Ostream。类似:

std::ostream &shortPrint(std::ostream &out) {
    //whatever you need here
    return out;
}

编辑:您需要的格式化,需要与返回课程的超载流操作员进行课程。但是,您需要保留对班上所需的流的引用。