13

とまったく同じであることがわかったので、明示的に呼び出しoperator<<た場合にどうなるかについて単純に興味がありました。だから私はそれをします、そしてそれは何か奇妙なものを印刷します:std::couta.operator()a()

#include <iostream>

using std::cout;

int main()
{
    cout.operator<<("Hello World");
}

Output: 0x80486a0

奇妙なことに、それはアドレスを出力します(アドレスはあなたにとって異なるかもしれませんが、それでもアドレスでなければなりません)。これが文字列のアドレスだと思っているので、文字列を出力するために逆参照してみます。

*( cout.operator<<("Hello World") );

しかし、私は非常に長いエラーを受け取ります

no match for operator* in '*std::cout.std::basic_ostream<...

これはかなり変だと思います。std::cout定義のどれも、これが異なる振る舞いを引き起こすと私に信じさせることはありません。また、演算子関数を明示的に呼び出しても違いはありません(または少なくともそうすべきです)。

では、なぜこの出力を取得するのですか?演算子を明示的に呼び出すときに、文字列自体ではなくアドレスを受け取るのはなぜですか?これはメモリ内のアドレスですか、それとも単なるガベージ出力ですか?どんな回答でも大歓迎です。

4

2 に答える 2

23

組み込み文字列の出力演算子、つまり、char const*引数としてのonは、のメンバーではありませんstd::ostream。aをとる演算子char const*は非メンバー関数であり、次のように呼び出されます。

operator<< (std::cout, "Hello World");

void const*ただし、 16進表記を使用してポインタの値をフォーマットするaを取るメンバーがいます。このメンバーは、ポインターをのメンバーに明示的に渡す場合に最適operator<< ()ですstd::ostream

aの結果の間接参照はoperator<<()機能しません:演算子は、単項オーバーロードstd::ostream&されていないaを返します。operator*()引数を逆参照するつもりなら、次のように呼びます。

std:cout.operator<< (*"Hello World");

ただし、これはchar const*文字列リテラルが減衰することを推測するだけで、個々の文字を生成しますH。文字出力関数もメンバー関数ではありませんが、整数の出力演算子は、つまり、の文字値を出力しますH。ASCIIを使用するシステムの場合は、になります72

于 2012-12-24T00:29:06.463 に答える
8

operator <<ここでの問題は、Cスタイルの文字列を出力ストリームに出力するのは実際にはフリー関数であり、のメンバー関数ではないということだと思いますbasic_ostream。ただし、を取り込んでそのアドレスを出力basic_ostreamするoperator<<関数はあります。void*その結果、メンバー関数として明示的に呼び出そうとoperator<<すると、文字列を出力するfree関数ではなく、Cスタイルの文字列のアドレスを出力するバージョンを呼び出していることになります。

あなたはこれを呼び出すことによって見ることができます

operator<< (std::cout, "Hello, world!");

これは実際に文字列を出力ます。

お役に立てれば!

于 2012-12-24T00:28:30.363 に答える