アプリ版:「スタンプのみでお礼する」機能のリリースについて

はじめまして。
質問があります。

class Foo {
・・・
// NG
friend ostream& operator<< (const ostream& out , Foo& c);
・・・
};

挿入演算子<<をオーバーロードするとき、挿入演算子関数の第1引数をconst ostream& outのようにconstを修飾するとコンパイルエラーに
なります。私としては、outの状態を変更したくないという意味
で修飾したのですが、なぜコンパイルエラーになるのかがわかりません。どうかご教授お願いします。
現在、Visual C++ 2005 Express Editionを使用しています。

A 回答 (5件)

>コメントアウトして実行してみたところ、コンパイルエラーが


>でなくなりました。outはやはり、変更されているのですね。
蛇足ですが、コンパイラは out が変更されるかどうかをチェックしているのではなくて、あくまでその宣言に const 指定がないことを見てエラーとしています。

したがって、本当は内容を変更していない hoge(ostream& out) を operator<<(const ostream& out, Foo& c) の実装中に使ってもエラーになります。
逆に、Foo の定義されたネームスペースの中で operator<<(const ostream& out, const std::string&) 等が定義されていれば、そっちを使うのでエラーにはなりません。

この回答への補足

koko_u_様へ
連絡が遅れました。すみませんでした。
ご回答ありがとうございます。
コンパイラがoutが変更されているかどうかをチェックしているのではなく、宣言の形式だけを見てエラーとしていることがわかり、そういう
ものなのだと、理解しています。
ただ、
>逆に、Foo の定義されたネームスペースの中で operator<<(const ostream& out, const std::string&) 等が定義されていれば、そっちを使うのでエラーにはなりません。

を動作確認しようと思い、サンプルコード全体をを単純に
namespace foo {}等で囲ってみてもエラーが出てしまいます。
多分私自身勘違いをしていると思いますが、具体的にどういうことなの
かご教授お願いします。別件で改めて質問をさせていただいても
かまいません。(本質問は良回答とさせていただきます。)

補足日時:2007/06/04 00:23
    • good
    • 0

>を動作確認しようと思い、サンプルコード全体をを単純に


>namespace foo {}等で囲ってみてもエラーが出てしまいます。
じゃあ、多分オレが間違えてる。

別の質問を立てて、ほんとに分っている人にアドバイスしてもらった方がいいでしょう。
    • good
    • 0
この回答へのお礼

koko_u_様へ
ご回答ありがとうございました。
いろいろとアドバイスしていただきまして、
感謝しております。

お礼日時:2007/06/04 01:48

>コンパイラがostream& outを使用しているのが原因なのですね。


ちがう。orz

「re-entry さんが」std::operator<<(ostream& out, ... ) を使っているからです。
コンパイラは親切にも out が変更されるよと教えてくれているのです。
    • good
    • 0
この回答へのお礼

koko_u様へ
ご回答ありがとうございました。
勘違いを指摘してくださいまして、感謝しております。
挿入演算子関数内のすべての定義内容を
コメントアウトして実行してみたところ、コンパイルエラーが
でなくなりました。outはやはり、変更されているのですね。
勉強になりました。
ありがとうございました。

お礼日時:2007/06/03 01:51

>確かにoperator<<(const ostream &out,Car &c)の定義内容は


>outオブジェクトの状態を変更する記述がないように思えるのですが、
>間違いでしょうか?

コンパイラから見ると
out << "ナンバー=" << c.num << ":" << "ガソリン=" << c.gas << endl;

で std::operator<<(ostream& out, ... ) を使用しているので、out が変更されない保証がないとしてコンパイルエラーになります。

また、実際 out に文字列を書き込めば、ストリームの状態が変更されるので const にはできません。
    • good
    • 0
この回答へのお礼

koko_u_様へ
ご回答ありがとうございました。
コンパイラがostream& outを使用しているのが原因なのですね。

お礼日時:2007/06/03 00:40

関数の中身がわからんので何とも言えませんが、


ostream を何らか操作すれば内容はかわると思いますが。

この回答への補足

koko_u_様へ
ご回答ありがとうございました。
サンプルを提示するべきでした。すみません。
----------------------------------------------------------------
#include <iostream>
using namespace std;

class Car {
private:
int num;
double gas;

public:
Car(int num,double gas);

friend void operator<<(const ostream &out,Car &c);
};

Car::Car(int num, double gas) {
this->num = num;
this->gas = gas;
}

void operator<<(const ostream &out,Car &c)
{
out << "ナンバー=" << c.num << ":"
<< "ガソリン=" << c.gas << endl;
}

int main()
{
Car *car = new Car(15, 26.7);

cout << *car;

return (0);
}
----------------------------------------------------------------
確かにoperator<<(const ostream &out,Car &c)の定義内容はoutオブジェクトの状態を変更する記述がないように思えるのですが、間違いでしょうか?どうかよろしくお願いします。

補足日時:2007/06/02 23:25
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!