簡體   English   中英

編寫一個簡單的函數,其功能類似於“ std :: cout”,但在末尾添加一個換行符

[英]Write a simple Function that works like “std::cout” but adds a Line Break at the End

在C ++中,有一個名為cout的標准庫函數,它使我可以將文本發送到控制台。 我確定你知道。

#include <iostream>
using std::cout;
cout << "Some Text " << 15 << " Other Text";

要在最后進行換行,我需要使用endl

cout << "Some Text " << 15 << " Other Text" << endl;

如何編寫名為coutl的函數,其功能類似於cout但還添加了likebreak? 我想使用cout使用的相同語法,尤其是<<操作符。

coutl << "Some Text " << 15 << " Other Text"; // coutl should add a linebreak

通過創建一個小的代理對象,在其析構函數中添加<< endl

class AddEndl
{
public:
  AddEndl(std::ostream& os) : _holder(new Holder(os)) {}

  template <class T>
  friend std::ostream& operator<< (const AddEndl& l, const T& t)
  {
    return (l._holder->_os) << t;
  }

private:
  struct Holder {
    Holder (std::ostream& os) : _os(os) {}
    ~Holder () { _os << std::endl; }

    std::ostream& _os;
  };

  mutable std::shared_ptr<Holder> _holder;
}

然后,您需要一個函數,以便獲得一個臨時的:

AddEndl wrap(std::ostream& os)
{
  return AddEndl(os);
}

然后應該可以工作:

wrap(std::cout) << "Hello";

更新:

我移動了析構函數,該析構函數將std::endl添加到std::shared_ptr<>所擁有的內部對象中,因此該示例不再依賴於Copy Elision。

僅在堆棧上創建的非臨時對象&具有完整的功能范圍是不可能的。 對象將如何知道這是對<< operator的最后一個鏈式調用?

您可以嘗試像這樣的駭客

class coutl
{
    public:
    ~coutl()
    {
        cout<<endl;
    }

    template<class T>
    coutl &operator<<(const T &x)
    {
        cout<<x;
        return *this;
    }

};

int main()
{
    coutl()<<"Hello"<<10<<"World";
    coutl()<<"Hello"<<20<<"World";
}

另一個類似的使用析構函數的技巧

class myostream
{
    public:
    ~myostream()
    {
        cout<<endl;
    }

    template<class T>
    myostream &operator<<(const T &x)
    {
        cout<<x;
        return *this;
    }

};

int main()
{
    {
        myostream coutl;
        coutl<<"Hello"<<10<<"World";
    }

    {
        myostream coutl;
        coutl<<"Hello"<<10<<"World";
    }

}

實際上的代碼

cout << "Some Text " << 15 << " Other Text" << endl;

調用運算符

// (pseudo code)
std::ostream& operator<<(std::ostream, [type] obj);

每次使用<<操作符幾次。 為了實現您想要的目標,您需要創建一個行為類似於std::ostream ,但“神奇地”知道何時發出對operator<<的“最后一次”調用並追加換行符。 如果沒有另一個跟蹤語句作用域的對象,恕我直言是不可能的。

coutl << "Some Text " << 15 << " Other Text"; // coutl should add a linebreak

你的想法無法實現。 實際上, cout << str1; 等效於cout.operator<<(str1) ,它返回cout本身的引用。 所以cout << a << b << c; 可以解析為((cout << a) << b) << c; 它不知道最后一次插入換行符的時間是什么時候。

暫無
暫無

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

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