出力用シフト演算子(<<)のオーバーロード
C++ の標準ライブラリでは cout などにシフト演算子(<<)を使って出力します。
std::cout << "Hello World!!" << std::endl;
これは iostream の上位クラスである ostream のシフト演算子(<<)のオーバーロードで実現されているのですが、これを自分で定義したクラス、構造体、列挙型などに対しても定義しておくと便利です。
これを定義しておくだけで、標準出力(cout), ファイル(ofstream), 文字列(stringstream)などにも自分で作ったクラス等を文字列として出力することが出来ます。
どうやるかというと、例えば点の構造体 Point があったとすると以下のように ostream クラスとシフト演算子(<<)の 2 項演算をオーバーロードします。
std::ostream &operator<<(std::ostream &out, const Point &tgt)
{
out << "(" << tgt.x << "," << tgt.y << ")";
return out;
}
この定義はクラス(構造体)定義の外で行うので、列挙型も定義できます。
ただし、クラスの場合は外なのでゲッターなどを用意しておく必要があります。
さらに以下のようなテンプレート関数を用意しておけば、簡単に文字列に変更できます。
template <typename T_t>
std::string to_str(const T_t &val)
{
std::stringstream ss;
ss << val;
return ss.str();
}
この関数は int 基本型を含めた ostream のシフト演算子(<<)をオーバーロードしているものであれば何でも文字列に変換できます。
to_str(5); // "5"
to_str(Point(2, 3)); // "(2, 3)"
ちなみに入力用のシフト演算子(>>)を使えば 値 → 文字列 変換の from_str() のような関数も作れます。ただし、入力用の場合は変換できなかった場合の例外処理も必要になってきます。
実は Boost ではこの to_str()、 from_str() のような関数をもっと一般的にした lexical_castというのが用意されているので、 Boost 使えばすぐ使えるようになります。
Qt の場合だとこのようなテンプレートを使った変換は残念ながら用意されていないのですが、 Qt で用意されているクラスはほとんど QDebug というデバッグ用の出力先への演算子がオーバーロードされているので、何も定義しなくてもダンプだけならできます。
qDebug() << QPoint(2, 3); // "QPoint(2, 3)"
Meadow で UTF-8(BOM 付き)を使う
そのときのまとめです。
まずは使えるように
以下のサイトなどに書いてあるのを参考させてもらって .emacs.el に記述を追加します。
http://memo358.blog18.fc2.com/blog-entry-19.html
; (set-language-environment "Japanese")よりも前に
(require 'un-define)
(require 'jisx0213)
新しくファイルを開いたときの文字コードも UTF-8 に
C-x C-f で新しくファイルを開いた場合の文字コードも UTF-8 にしたいので、
以下の行も .emacs.el に追加します。
(set-default-coding-systems 'sjis-dos)
(setq-default buffer-file-coding-system 'utf-8-ws-dos)
Windows ではファイル名やターミナルなどで使う他のコマンドが Shift-JIS だったりするので、
デフォルトは Shift-JIS で、ファイルを開いた時の文字コードで UTF-8(BOM) を指定する必要があります。
指定時の記述は utf-8 が BOM なしで、 utf-8-ws が BOM 付きです。
BOM
UTF-8 には BOM 付きと BOM なしとあって、この BOM というのは Byte Order Mark の略でエンディアンの違いによるバイト順を判定するためのバイトコードで、ファイルの先頭に付加されます。
ただ、UTF-16 とかの場合だとバイト順は重要なのですが、 UTF-8 は 1 バイトなので、バイト順というよりも UTF-8 を使っているという標識の意味でつけられます。
しかし、 英数字だけであれば ASCII コードと同じで、英語圏であれば変更してもソフトの対応が要らないというのが UTF-8 の売りでもあるので BOM なしという状態もあります。
この BOM ありなしはどちらも利点、欠点があって混在しているのですが、ソフトによっては BOM ついてないとエラーになるのもあれば、BOM ついているとエラーになるのもあったりといろいろやっかいなことを引き起こします。
VisualStudio2010 でも BOM なし UTF-8 で日本語使ってたりするとビルド時にワーニングがでてくるので、 ソースは BOM 付き UTF-8 にする必要があります。
Meadow が BOM を消しちゃうための対策
私が使っている Meadow が古いだけかもしれませんが、 Meadow では UTF-8 の対応が不十分です。
というのも、 BOM 付き UTF-8 のファイルをオープンした時、正常にファイル内容は読み取れているのですが、文字コードは BOM なし UTF-8 と判定してしまいます。
なのでこのファイルを Meadow で編集して保存すると BOM が取れています。
C-x [Return] f でファイルの文字コードを utf-8-ws にしてから保存すると BOM 付きで保存できるのですが、いちいち指定するのめんどくさいです。
そこで苦肉の策として C-x C-s でファイルを保存する際に自動的に文字コードを変更してから保存するように .emacs.el に次のコードを記述するようにしました。
(global-set-key "\C-x\C-s" '(lambda ()
(interactive)
(set-buffer-file-coding-system 'utf-8-ws-dos)
(save-buffer)))
(global-set-key "\C-x\C-S" 'save-buffer)
ここでは通常の保存も残しておきたかったので C-x C-S に変更しています。
これだと終了前やコンパイル前の y, n で聞かれる保存の場合には対応できていないので注意して下さい。
defadvice とか使えば、完全に保存する前に BOM 付きに変更できると思うので、文字コードは BOM 付き UTF-8 しか使わないという人は試してみるとどうでしょうか。
その場合は次のようなコードを追加します(ただし、ちゃんと試してないです)
(defadvice save-buffer-as-utf-8-ws (before save-buffer
activate compile)
(set-buffer-file-coding-system 'utf-8-ws-dos))
Emacs でのコーディングスタイルの設定
Emacs には GUI 風のカスタマイズ画面から値を設定する機能があります。
それを使うことにします。 まず、以下のコマンドを実行します
M-x custumize-group
そうするとグループをきかれるので、 c を入力します。
カスタマイズ画面になるので、そこの [C Default Style] でスタイルの [Show] をクリックして、各モードのところにスタイル名を入力します。

入力するスタイル名ですが、私の環境では以下のようなものがありました。
gnu, k&r, bsd, stroustrup, whitesmith, ellemtel, linux, python, java
ご自分の環境にあるものを見たい場合は *scratch* バッファで
c-style-alist
と書いた後に C-j を押してください。
スタイル設定のリストの一覧が出ます。いろいろ書いてあってわかりづらいですが、各リスト先頭要素の文字列が入力可能なスタイル名となります。
ついでにインデントを一括して修正する方法ですが、まず C-x h で全体を選択して C-M-\ とすると選択領域がインデントされます。
http://flex.ee.uec.ac.jp/texi/emacs-jp/emacs-jp_130.html