2012-03-04 9 views
14

私は完全に基本的なC++の質問をここに持っています。上記のコードの一部でC++で演算子の連鎖はどのように起こりますか?

#include <iostream> 
using namespace std; 

int main() { 
    int a = 255; 
    cout << hex << a << endl; // <----- 
} 

、どのようstd::coutステートメントが連鎖していますか?

私はcoutの実装が発生する連鎖を許可するようにcoutオブジェクトへの参照を返すということを理解し、それは次のように実行する必要がありますためには、これらに

(((cout << hex) << a) << endl) 

すなわち同等

  1. cout << hex
  2. cout << a
  3. cout << endl

aニーズの何らかの形で値がhex形式に変換するので、しかし、これは場合することはできません!

オペレータは実際に変換を実行するためにコンパイラによってどのように連鎖されていますか?

答えて

7

hexは通常実装されている方法です。

inline ios_base& 
hex(ios_base& __base) 
{ 
    __base.setf(ios_base::hex, ios_base::basefield); 
    return __base; 
} 

あなたが見ることができるように、hexは、それ自体で任意の変換を実行しません。その代わり、それはの印刷用の六角を使用するための基本ストリーム内のオプションを設定し、それ以降の時点で番号が渡されます。

EDIT(コメントへの応答で)

HAMMARが正しく指摘すると、パズルの他の部分はhex(ios_base& __base)が呼び出されている方法です。このシグネチャを持つ<<演算子のオーバーロードがあります:

ostream& operator <<(ostream& (*)(ostream&)) 

このオーバーロードは、stream manipulatorsの基本的な実装の詳細です。それはhexを呼び出し、それはその "魔法"(もちろんあなたに魔法のように聞こえてはいけません)を行うことができますこのオーバーロードです。

+1

パズルの他の部分である 'ostream&operator <<(ostream&(*)(ostream&))'オーバーロードがあります。これは 'hex 'のようなマニピュレータが実際に呼び出される方法です。 – hammar

+0

@ハマー素晴らしい観察!コメントをいただき、ありがとうございました。私はこの要点を反映する答えを編集しました。 – dasblinkenlight

22

あなたはそれを正しく持っています、それはまさにその動作です。 hexには、operator<<関数に渡されたときにcoutオブジェクトの内部状態を変更する特別な型があります。その後、内部状態は、を介してどのように将来の値がcoutに渡されるかを決定します。

std::hexは、関数であることがあります。 cout << hexは16進数の関数をそのようには呼びません。それは、16進数の関数へのポインタをのオーバーロード(ostream)に渡し、特定のシグネチャを持つ関数ポインタを受け入れます。 hex()は、その関数ポインタを介して演算子の実装内部から呼び出され、私が知る限りそこからostreamオブジェクトを変更します。

+0

'hex 'は*特殊タイプ*ではありません。それは関数です。 (または、単に 'hex' *が特殊な型を持っていると言っても意味がありません)* – Nawaz

+1

はい、関数型を持っています。これは、どのoperator <<オーバーロードが呼び出されるかを決定する型です。 'cout << hex'は' hex'関数をそれほど呼び出さず、16進関数へのポインタを特定の署名を持つ関数ポインタを受け入れる 'operator <<'オーバーロードに渡します。 'hex()'は、私が知る限り、演算子の実装内部から呼び出されます。 – pmdj

+0

+1。今、答えは良く見えます。 – Nawaz

2

std::hexは実際にはstd::coutオブジェクト内にフラグを設定します。このフラグはリセットIIRCまで保持されます。 operator<<自体は左から右に評価されるので、あなたの括弧は正しいです。

1

私の見解から、hexは単なるパッケージオブジェクトであり、coutオブジェクトに副作用があります。この後、coutは16進値のみを出力します。

関連する問題