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

时间:2014-01-23 09:47:21

标签: c++ constructor operator-overloading cout

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

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

更短,即如果我们编写代码,就会发生同样的事情:

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

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

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

有人告诉我,最容易做到的就是创建一个名为“shortPrint”的课程。

任何人都可以帮我解决这个问题吗?

首先,我想说我只需要实现构造函数和运算符&lt;&lt;重载,但我不确定在那种情况下该怎么做。

4 个答案:

答案 0 :(得分:6)

是使用适当的重载运算符创建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;
  }
};

答案 1 :(得分:2)

您可以执行以下操作:

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;

但是这个实现不适用于rvalues:

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

答案 2 :(得分:1)

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

#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节here)。

希望有所帮助。

答案 3 :(得分:0)

从函数中返回ostream。类似的东西:

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

编辑:你需要的那种格式化,你需要创建一个带有重载流操作符的类来返回类。但是你需要保持对类中所需流的引用。