operator演算子について – 固定ページ 2 – プログラミング – Home

通知
すべてクリア

[解決済] operator演算子について

固定ページ 2 / 3

tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

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つ上がってしまうのだな


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> そーいうわけで 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;
}


返信引用
松雄
 松雄
(@松雄)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

tetrapodさん
勉強になります。
>いきなり template 化は難しいかもしれないな
>ostream は basic_ostream<char, char_traits<char> > の typedef である。
>basic_ostream<wchar_t, char_traits<wchar_t> > が作れれば wcout に出せる。
>というあたりを理解しておかないと不可能だろう。
MSDNを早速調べたところちゃんと記載されてました、当然ですが!
なんとなくではありますが、今後の開発でどこまで意識してどのような手順で進めるか
理解できました。ありがとうございます。

たいちうさん
早速、例までご用意くださってありがとうございます。私も早速修正します。

結論
stream系はどうも苦手意識していたせいか理解度が全くありませんでした。
皆さんはどこで知識を得たのですか!?一番の疑問です。
参考サイトなどあれば教えて下さい。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> 昨日書いたコードを置換してみた

wideなストリームにnarrowな文字列を << してますょ?

> 皆さんはどこで知識を得たのですか

場数を踏む。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

場数には御意

こーいうのって結局興味があるか否かで決まると思うのココロ
・template ってなんだか面白そう、でも難しいかも
・とりあえず例題というかサンプルというか、ないかなー
・ってコンパイラをインストールしたらシステムヘッダがあるぢゃん!
ということで <iostream> とか <vector> とか <algorithm> とかを見てみる。
あたりから始まるのだと思うのよね

んで <algorithm> なんかは中見るとどえらく単純なんでびっくりとか、
で、それを応用している人のページ(επιστημηさんの記事とか)を
みつけてくると、えらく複雑そうなことをあっさり数行で実装していて、
なぜにこんな簡単なコードでこれだけ複雑そうなことが出来るのか悩んだりとか。

興味を持つ→調べてみる→新鮮な驚き→もっと興味を持つ、の正のスパイラル。

boost の中身を読んでバグ発見修正とかそこまで至るとマニアの世界なんだけど


返信引用
松雄
 松雄
(@松雄)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

επιστημηさん
> 場数を踏む。
私の場合、場数を踏む前の基礎知識が不十分なのが問題です。

申し訳ありませんが、この場を借りましてここで質問させて下さい。

TCHAR szBuffer[256];
_stprintf(szBuffer, %04hX, -12);

--結果--
FFF4

これをostringstreamでやるにはどうすればいいですか?
oss << setw(4) << hex << uppercase << -12 << endl;

--結果--
FFFFFFF4

できないのでしょうか?


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

-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 表示になるのだな


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> 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;
};


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> 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なストリームの場合もあり、問題があるように思うのですが。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

char, wchar_t で部分的な特殊化をしてあげにゃならんかなー
めんどくさげー orz


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

そのための 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)


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

いや、文字はそれでいいけど文字列が...


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

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;
}


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

X座標:12, Y座標:-31と書かせたくなったらどないすんの、と。
# なんにせよめんどっちーんだこれが ^^;


返信引用
松雄
 松雄
(@松雄)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

tetrapodさん
επιστημηさん
有難うございます。
oss << setw(4) << hex << uppercase << short(-12) << endl;

で無事解決です。
皆さんテンプレートで盛り上がっていますが、やはりレベルが高すぎて
意味不明です。参考にさせてもらいます。


返信引用
固定ページ 2 / 3

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました