No Such Blog or Diary
サブクラス判定
ちゃんと探せば STL や Boost に is_convertible と is_base とかがあった.肝を抜き出してみるとこんなもん.
#include <iostream> using namespace std; template<typename From, typename To> struct isConvertible { static char test(To); static long test(...); // variable argument で逃げる static From from(); static const bool value = sizeof(test(from())) == 1; }; class A {}; class B : public A {}; int main(int argc, char *argv[]) { cout << isConvertible<A, B>::value << endl; cout << isConvertible<B, A>::value << endl; return 0; }
test 関数の呼び出しで From から To に変換できる場合は test(To) が選択され,sizeof(test(from())) = 1 となるので value = true となる.そうでなければ test(...) が選択され sizeof(test(from())) != 1 で value = false と.variable arguments 使って型指定をなくせるのに気づかなかった...
もう少し高度なトリックを使うと次の is_base のメイン部分になるらしい.
#include <iostream> using namespace std; template <typename Super, typename Sub> struct isSuperclasOf { template<typename T> static char test(Sub &, T); static long test(Super &, int); struct C { operator Super &() const; operator Sub &(); }; static const bool value = sizeof(test(C(), 0)) == 1; }; class A {}; class B : public A {}; int main(int argc, char *argv[]) { cout << isSuperclasOf<A, B>::value << endl; cout << isSuperclasOf<B, A>::value << endl; return 0; }
http://tinyurl.com/502f と http://tinyurl.com/6jvyq に原理が書いてある.結局はある変換系列が他の変換系列の prefix になっているなら短い型変換が優先で,テンプレート有り関数とテンプレート無し関数では無い関数が優先であることを使っているらしい.Super が Sub の親クラスの場合,test(Super&, int) が呼ばれるには C → Sub → Super の変換列をとり( C → C const → Super 側は無視される),一方で test(Sub&, int) は C → Sub という変換列となる.このとき, C → Sub が C → Sub → Super の prefix になっているので test(Sub&, int) が選択される.よって,sizeof(test(C(), 0)) が 1 になるので value が true になる.Super が Sub の親クラスで無い場合は,test(Super&, int) が呼ばれるには C → C const → Super という変換列となり,これは C → Sub に吸収されないので test(Super&, int) と test(Sub&, int) の可能性がある.しかし,test(Sub&, int) に関してはテンプレートの instantiation があるので test(Super&, int) が選択される.よって,この場合は sizeof(test(C(), 0)) が 1 でないので value が false になる.
よくかんがえるもんだなぁ.
- Comments: 0
- TrackBack (Close): -
C++ であるクラスを継承しているかどうかの判定って
できるかなぁと.
#include <iostream> using namespace std; template <typename E> class Eq { virtual bool operator==(const E& e) const = 0; }; class Int : public Eq <Int> { public: int num; bool operator==(const Int& e) const { return this->num == e.num; } Int(int num) { this->num = num; } }; template <typename A> struct HasEq { enum {val = 0}; }; template <typename A> struct HasEq< Eq<A> > { enum {val = 1}; }; int main(int argc, char *argv[]) { cout << HasEq<Int>::val << endl; return 0; }
このコードの出力が 1 になってほしいと.このコードでは 0 を出力するほうに実体化されるので,これを避けたい.キャストを入れて 0 出力側で実体化を失敗させればいいのかな?
- Comments: 0
- TrackBack (Close): -
帰省より復帰
- 2006-01-04 (Wed)
- 一般
けっきょく綺麗な富士山を見ることなく帰省より復帰.もう少し晴れてくれれば... んで,帰ってきたら飯がなかったので食材を買ってシチューを作ったのだが,煮込んでいる最中にいつの間にかコンロの火が消えていたことに気づく.風呂に入ってた間に吹きこぼしで消えたのだろうか,微妙に危なかった.新年早々ガス爆発はいやである.さて修論でも書くか.
- Comments: 0
- TrackBack (Close): -
三が日終わり
- 2006-01-03 (Tue)
- 一般
銀行のATMも明日には動きはじめるのだろうか? 古畑任三郎ファイナル一日目は最後にどう犯人を負かすのだろうとか考えてたら結局15年前のネタで引っ張るだけなのね.こういう場合って時効とかどうなるんだろうとか気になるが,少々すっきりしない終わりだなぁと.そして文花帖は54シーンでExまであと12...
- Comments: 0
- TrackBack (Close): -
正月に出かける
- 2006-01-02 (Mon)
- 一般
猫をバッグにいれ頭だけ出させて買い物などに出かけたけど,ほんと正月というのに出歩いてる人が多い.むかしは店もろくに開いてなかったのに今じゃ元日から平気であいてるし.むしろ安売りしてるから元旦から並ばないといけないのかも.ついでにお飾り付の車もあまり見かけなくなった.ひっくり返ってるのを見るのが面白かったのに.お飾りが完全に消えてしまうのもそう遠くないのかもしれない.それにしても文花帖Ex出現条件が66シーン取得ってのはちとムズイ.まだ43シーンしか取れてないしレベル10とか取れる気がしないし... どうなることやら.
- Comments: 0
- TrackBack (Close): -
初詣へ
- 2006-01-01 (Sun)
- 一般
毎年のごとく朝の4時ごろに三島大社へと初詣に出かけた.大晦日から来ていた連中は帰ってるし,朝一で来る連中が来るにはまだ早い時間ということで,この時間帯が一番すいていて動きやすい.ちと寒いけど.そんでもってとった行動は賽銭投げてお守り買って,おみくじ引いたら小吉とこれも例年通り.新年になったという実感は特に無いが,とりあえず今年も適当に頑張ろうかと思う.それにしてもこんな寒い中バイトの巫女さん達はよく袴姿で仕事できるなぁ.聞いた話では日給で1万円とかいってたからちと割に合わない気がするし.あの姿になりたい人たちがやっているのだろうか?動機が良く分からん.
- Comments: 0
- TrackBack (Close): -