「Barton Nackmanトリックによる静的なタイプ階層において,クラス内にネストされて定義された(あるいはclassスコープでtypedefされた)クラスをその親クラスのネストクラスとして定義する方法」
っつーのを前からちょこっと考えていたけど,allocatorで使われているrebindのようなやり方で解決できるんじゃないかと考えて実装してみる.
#includeusing namespace std; template class A { private: template struct rebind { typedef typename U::X X; }; public: typedef rebind<> bind; }; class B : public A<B> { public: struct X { static void say(){cout << "B::X" << endl;} }; }; class C : public A { public: struct X { static void say(){cout << "C::X" << endl;} }; }; template void say(const A &a) { A ::bind::X::say(); } int main(int argc, char* argv[]) { B b; C c; say(b); say(c); return 0; }
上のコードは<B>の部分の山型括弧が倍角になっているので注意w
コンパイルしたらちゃんと期待通りに動いた.(゜д゜)ウマー
肝はAからB::XやC::Xを直接参照するとだめなので,テンプレートクラスのbind(実体はrebind
これによってA::bind::Xの実体化が,実際にそれを呼ぶとき(上のコードではグローバル関数のsay)まで遅延されるのでOK・・・と.
逆に言えば,テンプレートを挟まないとだめなのでこれ以上簡単な書き方(A::Xみたいなの)はないと思うがどうか?