0

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
4

4 に答える 4

6

<< 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<>て、例がコピーの省略に依存しないようにします。

于 2012-10-20T11:26:17.880 に答える
1

スタック上に作成され、完全な関数スコープを持つ非一時オブジェクトだけでは不可能です。オブジェクトは、これがチェーン呼び出しの最後のものであるかをどのようにして知ることができ<< 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";
    }

}
于 2012-10-20T11:22:43.447 に答える
0

実際、コード

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

演算子関数を呼び出します

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

<<演算子の使用ごとに数回。目的を達成するには、のように動作するクラスを作成する必要がありますがstd::ostream、「魔法のように」は、「最後の」呼び出しがいつoperator<<発行されたかを認識し、改行を追加します。ステートメントスコープを追跡する別のオブジェクトがなければ、これは不可能です。

于 2012-10-20T11:28:46.073 に答える
0

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

あなたの考えは実現できません。実際、これはcout自体の参照を返すのcout << str1;と同じです。cout.operator<<(str1)したがって、次のcout << a << b << c;ように解決できます ((cout << a) << b) << c;。改行を挿入する最後の呼び出しがいつであるかはわかりません。

于 2012-10-20T14:26:32.983 に答える