operator << 演算子を使ったのですが、以下のエラーが出てしまいます。
どなたかご指導お願いいたします。
--エラーの内容--
binary '<<' : no operator defined which takes a right-hand operand of type
'class hoge_timer' (or there is no acceptable conversion)
--クラス定義--
class hoge_timer
{
public:
hoge_timer (){ ::GetLocalTime((LPSYSTEMTIME) &systime); }
friend ostringstream& operator << (ostringstream& oss, hoge_timer& rhs)
{
oss << setw(4) << setfill('0') << rhs.systime.wYear << '.'
<< setw(2) << setfill('0') << rhs.systime.wMonth << '.'
<< setw(2) << setfill('0') << rhs.systime.wDay
<< ' '
<< setw(2) << setfill('0') << rhs.systime.wHour << ':'
<< setw(2) << setfill('0') << rhs.systime.wMinute << ':'
<< setw(2) << setfill('0') << rhs.systime.wSecond << '.'
<< setw(3) << setfill('0') << rhs.systime.wMilliseconds
<< ' ';
return oss;
}
protected:
SYSTEMTIME systime;
};
--実行部--
void hoge::func(void)
{
hoge_timer timer;
ostringstream oss;
oss.setf(ios::left, ios::adjustfield);
oss << setw(14)
<< timer;
}
ostreamなら作ったことがある。
↓じゃ駄目かな?
class hoge_timer {
public:
// (略)
friend ostream& operator << (ostream& oss, hoge_timer& rhs) {
oss << setw(4) << setfill('0') << rhs.systime.wYear << '.'
<< setw(2) << setfill('0') << rhs.systime.wMonth << '.'
<< setw(2) << setfill('0') << rhs.systime.wDay
<< ' '
<< setw(2) << setfill('0') << rhs.systime.wHour << ':'
<< setw(2) << setfill('0') << rhs.systime.wMinute << ':'
<< setw(2) << setfill('0') << rhs.systime.wSecond << '.'
<< setw(3) << setfill('0') << rhs.systime.wMilliseconds
<< ' ';
return oss;
}
};
void hoge::func() {
hoge_timer timer;
cout << setw(14) << timer;
}
いや、最終的に表示するかは別として文字列がほしいのか。
調べないと分からなくけど今調べる時間がない。
時間が取れる頃までには回答が付いていると思うのでパスします。ごめんなさい。
たいちうさん、ありがとうございます。
コンパイルは無事通りました。これから動作確認してみます。
ostringstreamではまずいのでしょうか?
>--エラーの内容--
>binary '<<' : no operator defined which takes a right-hand operand of type
>'class hoge_timer' (or there is no acceptable conversion)
oss << setw(14)の戻り値がostream&型だからではないでしょうか。
dynamic_cast< ostringstream& >( oss << setw(14) ) << timer;
とでもするのかな。
解決してるっポいけど。
> 以下のエラーが出てしまいます。
「どこで」そのエラーが出たか くらいは書いとくのが
渡世の義理ってもんじゃないすかね。
これ以上は私の手には負えないようです。よろしければどなたかヘルプ。
#include <iostream>
#include <sstream>
using namespace std;
class Hoge {
public:
int x;
int y;
Hoge(int x0, int y0) : x(x0), y(y0) {}
friend ostringstream& operator<<(ostringstream &oss, Hoge &hoge) {
oss << oss( << hoge.x << , << hoge.y << );
return oss;
}
};
// (a)
ostream& operator<<(ostream &os, Hoge &hoge) {
os << os ( << hoge.x << , << hoge.y << );
return os;
}
int main() {
// (1)
Hoge hoge(12, 34);
cout << (1) : << hoge << - << hoge << endl;
// (2)
ostringstream oss;
oss << hoge << - << hoge;
cout << (2) : << oss.str() << endl;
oss.str(");
// (3)
static_cast<ostringstream&>(oss << hoge << - ) << hoge;
cout << (3) : << oss.str() << endl;
// quit
cout << End. << endl;
cin.get();
return 0;
}
// 実行結果(VC++2003 SP6, WinXP SP3)
(1) : os (12, 34) - os (12, 34)
(2) : oss(12, 34) - os (12, 34)
(3) : oss(12, 34) - oss(12, 34)
松雄さんのエラーは、iijimaさんのご指摘の通り、oss::operator<<()の戻り値が
ostream&型で、
該当する(a)のようなコードが無いからおきているのだと思う。
(2)のような呼び出しで変わっていることが確認できたと思う。
(3)のように書けば、oss用のコードを呼び出せるが、
キャストなしで書くスマートな方法が思いつかない。
Hogeをもっときれいに書けるのかな?
# 私が作るならば、hoge_timerにstring型を返すgetTimeString()とかを書くけどね。
> ostringstreamではまずいのでしょうか?
んー...
ostream& operator<<(ostream& stream, const hoge_timer& ht)
では困ったことでも起こるのでしょうか?
ostreamに<<できるようにしておけば
ファイルだろが画面だろがストリームだろが、
いろんなもんに<<できて便利だと思うんだけど。
> ostreamに<<できるようにしておけば
> ファイルだろが画面だろがストリームだろが、
> いろんなもんに<<できて便利だと思うんだけど。
ですよね。
// (4)
stringstream ss;
ss << hoge << - << hoge;
cout << (4) : << ss.str() << endl;
iijimaさん、επιστημηさん、たいちうさん
大変ありがとうございます。そして返事が遅くなり申し訳ありませんでした。
いろいろご指導通りやりました。無事解決できました。
>無事解決できました。
どのように解決したのかも書き添えてもらえるとgood.
iijimaさん、おっしゃる通りです。
改めまして。。。
以下を実装したところ、エラーも無くなり動作も完璧でした。
--クラス内--
friend ostream& operator << (ostream& os, hoge_timer& rhs)
{
os << setw(4) << setfill('0') << rhs.systime.wYear << DOTCHAR
<< setw(2) << setfill('0') << rhs.systime.wMonth << DOTCHAR
<< setw(2) << setfill('0') << rhs.systime.wDay
<< SPACECHAR
<< setw(2) << setfill('0') << rhs.systime.wHour << COLONCHAR
<< setw(2) << setfill('0') << rhs.systime.wMinute << COLONCHAR
<< setw(2) << setfill('0') << rhs.systime.wSecond << DOTCHAR
<< setw(3) << setfill('0') << rhs.systime.wMilliseconds
<< SPACECHAR;
return os;
}
friend ostringstream& operator << (ostringstream& oss, hoge_timer& rhs)
{
oss << setw(4) << setfill('0') << rhs.systime.wYear << DOTCHAR
<< setw(2) << setfill('0') << rhs.systime.wMonth << DOTCHAR
<< setw(2) << setfill('0') << rhs.systime.wDay
<< SPACECHAR
<< setw(2) << setfill('0') << rhs.systime.wHour << COLONCHAR
<< setw(2) << setfill('0') << rhs.systime.wMinute << COLONCHAR
<< setw(2) << setfill('0') << rhs.systime.wSecond << DOTCHAR
<< setw(3) << setfill('0') << rhs.systime.wMilliseconds
<< SPACECHAR;
return oss;
}
void hoge::func() {
hoge_timer timer;
cout << setw(14) << timer; // O.K.
cout << timer; // O.K.
}
これで本当に解決です。
皆さん、ご指導有難うございました。
ostream, ostringstream の二つの版を実装したのはナゼですか?
ostream だけで十分に思えるのですけど。
ostringstream は ostream から派生しているので
ostream& で ostringstream や ofstream を保持できるわけで。
# つまり ostringstream& 版は不要、っつーことで
ついでに template 化しておけば wcout にも出力できる、っと
あと注意深く必要なところにだけ const をつけておくと完璧かな
みなさん何度もアドバイスありがとうございます。
επιστημηさん
おっしゃる通りでした。最初、両方ないとコンパイルが通らなかった気がして
そのままでした。うっかり間違って理解するところでした。初心者なもので。。。
tetrapodさん
constとはこんな感じですか!?
friend ostream& operator << (ostream& os, cosnt hoge_timer& rhs)
テンプレートはやった事がないので良く分かりませんでした。
template<class T = ostream>
friend T& operator << (T& lhs, cosnt hoge_timer& rhs)
調べて考えましたがやはり不明でした。