const は正解!100点
ostream に const をつけては×なのだな。
いきなり template 化は難しいかもしれないな
ostream は basic_ostream<char, char_traits<char> > の typedef である。
basic_ostream<wchar_t, char_traits<wchar_t> > が作れれば wcout に出せる。
というあたりを理解しておかないと不可能だろう。
そーいうわけで unicode 出力対応のため template にするのであれば
ostream を std::basic_ostream<E,T> に置換することになる。
class hoge_timer { ...
template<typename E, typename T> friend
std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& os,
const hoge_timer& x) {
...
return os;
}
}
ということになるわけだ (operator << をクラス内部で定義していい場合)
クラス外で friend にするためには結構めんどくさい手続きが必要であったりして
難度が1つ上がってしまうのだな
> そーいうわけで unicode 出力対応のため template にするのであれば
> ostream を std::basic_ostream<E,T> に置換することになる。
勉強になるな。私も感謝です。昨日書いたコードを置換してみた。
#include <iostream>
#include <sstream>
using namespace std;
class Hoge {
int x_;
int y_;
public:
Hoge(int x, int y) : x_(x), y_(y) {}
template<typename E, typename T> friend
basic_ostream<E, T>& operator<<(basic_ostream<E, T> &os, const Hoge &hoge) {
os << ( << hoge.x_ << , << hoge.y_ << );
return os;
}
};
int main() {
// (1) coutに出力
Hoge hoge(12, 34);
cout << (1) : << hoge << - << hoge << endl;
// (2) 文字列を取得
stringstream ss;
ss << hoge << - << hoge;
cout << (2) : << ss.str() << endl;
// (3) wcoutに出力
wcout << (3) : << hoge << - << hoge << endl;
return 0;
}
tetrapodさん
勉強になります。
>いきなり template 化は難しいかもしれないな
>ostream は basic_ostream<char, char_traits<char> > の typedef である。
>basic_ostream<wchar_t, char_traits<wchar_t> > が作れれば wcout に出せる。
>というあたりを理解しておかないと不可能だろう。
MSDNを早速調べたところちゃんと記載されてました、当然ですが!
なんとなくではありますが、今後の開発でどこまで意識してどのような手順で進めるか
理解できました。ありがとうございます。
たいちうさん
早速、例までご用意くださってありがとうございます。私も早速修正します。
結論
stream系はどうも苦手意識していたせいか理解度が全くありませんでした。
皆さんはどこで知識を得たのですか!?一番の疑問です。
参考サイトなどあれば教えて下さい。
> 昨日書いたコードを置換してみた
wideなストリームにnarrowな文字列を << してますょ?
> 皆さんはどこで知識を得たのですか
場数を踏む。
場数には御意
こーいうのって結局興味があるか否かで決まると思うのココロ
・template ってなんだか面白そう、でも難しいかも
・とりあえず例題というかサンプルというか、ないかなー
・ってコンパイラをインストールしたらシステムヘッダがあるぢゃん!
ということで <iostream> とか <vector> とか <algorithm> とかを見てみる。
あたりから始まるのだと思うのよね
んで <algorithm> なんかは中見るとどえらく単純なんでびっくりとか、
で、それを応用している人のページ(επιστημηさんの記事とか)を
みつけてくると、えらく複雑そうなことをあっさり数行で実装していて、
なぜにこんな簡単なコードでこれだけ複雑そうなことが出来るのか悩んだりとか。
興味を持つ→調べてみる→新鮮な驚き→もっと興味を持つ、の正のスパイラル。
boost の中身を読んでバグ発見修正とかそこまで至るとマニアの世界なんだけど
επιστημηさん
> 場数を踏む。
私の場合、場数を踏む前の基礎知識が不十分なのが問題です。
申し訳ありませんが、この場を借りましてここで質問させて下さい。
TCHAR szBuffer[256];
_stprintf(szBuffer, %04hX, -12);
--結果--
FFF4
これをostringstreamでやるにはどうすればいいですか?
oss << setw(4) << hex << uppercase << -12 << endl;
--結果--
FFFFFFF4
できないのでしょうか?
-12 とだけ書いたならその型は int になってしまうわけだ
int の -12 は (VC++ では) FFFFFFF4 なので正しい結果が得られている。
言語規格書によれば整数定数の型を long と明示することはできても
short と明示する手段は用意されていないので (片手落ちだね)
cout << setw(4) << hex << short(-12) << endl;
とするのだろうな
printf は可変個引数な関数なので short を渡すことは原理的に出来ないわけで
(暗黙の型変換によって short を渡そうとしても int に変換されている)
%hX は、「対応する実引数は int であるが、それを short に変換して表示」
という意味になる。
だから -12 という int 型の値を渡しても short 表示になるのだな
> cout << setw(4) << hex << short(-12) << endl;
> とするのだろうな
ですねー。
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << hex << uppercase << setfill('0');
cout << setw(4) << short( 12) << endl;
cout << setw(4) << short(-12) << endl;
};
> wideなストリームにnarrowな文字列を << してますょ?
ご指摘ありがとうございます。こっちは直せた。
wcout << L(3) : << hoge << L - << hoge << endl;
でも、↓これが直せない。
template<typename E, typename T> friend
basic_ostream<E, T>& operator<<(basic_ostream<E, T> &os, const Hoge &hoge) {
os << ( << hoge.x_ << , << hoge.y_ << );
return os;
}
wideなストリームの場合もあり、問題があるように思うのですが。
char, wchar_t で部分的な特殊化をしてあげにゃならんかなー
めんどくさげー orz
そのための char_traits ですよ
static E char_traits::to_char_type(const int_type& ch) を使って
os << T::to_char_type('(') << hoge.x_ ....;
と、ここまで書いて <complex> の中を見てみたら char_traits::to_char_type を
使ってないでやんの (cygwin-gcc-3.4.4)
いや、文字はそれでいいけど文字列が...
std::endlの定義を調べてみると、basic_ostream::widen(char)というのがある。
これを使ってみた。
変換部分をテンプレート関数にして外に出せば、まぁ我慢して使える範囲かな?
template<typename E, typename T> friend
basic_ostream<E, T>& operator<<(basic_ostream<E, T> &os, const Hoge &hoge) {
const char s0[3][3] = { (, , , ) };
basic_string<E> s1[3];
for (int i = 0; i < 3; i++) {
for (int j = 0; s0[i][j]; j++)
s1[i].push_back(os.widen(s0[i][j]));
}
os << s1[0] << hoge.x_ << s1[1] << hoge.y_ << s1[2];
return os;
}
X座標:12, Y座標:-31と書かせたくなったらどないすんの、と。
# なんにせよめんどっちーんだこれが ^^;
tetrapodさん
επιστημηさん
有難うございます。
oss << setw(4) << hex << uppercase << short(-12) << endl;
で無事解決です。
皆さんテンプレートで盛り上がっていますが、やはりレベルが高すぎて
意味不明です。参考にさせてもらいます。