簡體   English   中英

運算符<<在構造函數中重載

[英]operator << overloading in a constructor

我正在調試程序,我想從該模式進行打印:

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

更短,也就是說,如果我們編寫代碼,則應該發生相同的事情:

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

注意:變量數量沒有限制,可以為1,也可以為20,因此也可以使用:

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

有人告訴我,最簡單的方法就是創建一個稱為“ shortPrint”的類。

誰能幫我解決這個問題?

首先,我會說我只需要實現一個構造函數和一個運算符<<重載,但是我不確定在那種情況下該怎么做。

是的,使用適當的重載運算符創建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;

但是,此實現不適用於右值:

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

這是因為類_ostream_wrap保留_ostream_wrap的引用,對於右值,它需要進行復制。 要制作副本,您需要兩個實現(這將是最終版本):

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

編輯:您需要的格式化類型,您需要使用返回該類的重載流運算符來創建一個類。 但是您需要在類中保留對所需流的引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM