meryngii.neta

今日も新たな"ネタ"を求めて。

implicit_cast

暗黙のキャストを明示的に行いたい場合がある。
http://groups.google.com/group/comp.lang.c++.moderated/browse_frm/thread/048fb906e8641f4c/
例えば変換演算子を呼び出したいときなどは、

struct A { void f() { } };
struct B { operator A() { return A(); } };

int main()
{
	B b;
	(A)b.f(); // Cキャストは汚い
	b.operator A().f(); // 見栄えが良くない
	A a = b; a.f(); // 美しいが長い
	implicit_cast<A>(b).f(); // 美しい
}

という感じに、implicit_castを使うと簡潔でC++らしく書ける。
ストリームでも便利に使える。

std::cout << (int)'A'
	<< implicit_cast<int>('A');

Boostでのimplicit_castの実装は、
http://d.hatena.ne.jp/uskz/20060608/p1

namespace boost
{
	namespace mpl
	{
		template <class T>
		struct identity { typedef T type; };
	}	
	
	template <typename T>
	inline T implicit_cast(typename mpl::identity<T>::type x)
	{
		return x;
	}
}

となっている。xの型は複雑なため推論されずにテンプレート引数が必要になる。この他にもidentifyは様々な用途があって、Modern C++ Designでも扱われている。(こっちでの名前はType2Type)
MSDNには違った実装があった。
http://msdn.microsoft.com/ja-jp/library/cc440191.aspx

template <typename FROM, typename TO>
inline TO implicit_cast(FROM const &x)
{
	return x;
}

これはテンプレート引数が逆な気がする。

template <typename TO, typename FROM>
inline TO implicit_cast(FROM const &x)
{
	return x;
}

私はこの実装の方が簡単なので好きだが、もしかしたらBoostの実装の方がよい理由があるのかもしれない。