テンプレートのtypedefで詰まったので書いておきます。
エラトステネスのふるい
サンプルは素数のチェック用にstd::mapのアダプタを作ってみました。template class Marker<T_Element>は、
mark, eraseで要素に対してフラグを立て、foundでフラグを参照します。
(ほとんどメンバ変数のm_mapに委譲しています。)
(まあ、本当はトラバース時にオブジェクト参照に対して
visitフラグを立てるためのコンテナアダプタでしたが、
サンプルではunsignedを要素にしました)
#include <map> #include <iostream> /* container adaptor for map<T,bool>.*/ template<typename T_Element> class Marker { public: typedef T_Element element; typedef std::map<T_Element, bool> map; typedef map::iterator iterator; private: Marker::map m_map; public: Marker::iterator begin() { return m_map.begin(); } Marker::iterator end() { return m_map.end(); } bool found(Marker::element val)const { return m_map.find(val) != m_map.end(); } void mark(Marker::element val) { m_map[val] = true; } void erase(Marker::element val) { Marker::iterator i = m_map.find(val); if (i != m_map.end()){ m_map.erase(i); } } }; using namespace std; int main() { Marker<unsigned> sieve; unsigned n=2; const unsigned max=100; for (unsigned i=2; i<max; ++i) { sieve.mark(i); } for (unsigned i=2; i*i<max; ++i) { if (sieve.found(i)) { for (unsigned j=i*2; j<max; j+=i) { sieve.erase(j); } } } for (Marker<unsigned>::iterator i=sieve.begin(); i!=sieve.end();++i) { std::cout << i->first << " "; } return 0; }
ところが、g++でコンパイルしたところ、
(std::map<T_Element>は、Marker<T_Element>から派生してないよ)typedef std::map<T_Element, bool> map; typedef map::iterator iterator; type ‘std::map<T_Element, bool, std::less<_Key>, std::allocator<std::pair<const T_Element, bool> > >’ is not derived from type ‘Marker<T_Element>’
というエラーをいただきました。
う~ん。。。
typename
結果的には、これは、typedef typename map::iterator iteratorと、キーワードtypenameを使うことでOKです。
私としてはMarker<T_Element>::map はstd::map<T_Element>だから、
内部に型iteratorをもつはずと暗黙のうちに仮定しているのですが、
コンパイラ的には、すべてのT_Elementについて
std::map<T_Element>がiteratorを「型として」持つとは言い切れないとみているのでしょうか。
(あるいはそのチェックが面倒)
そこで、typenameで、「シンボルmap::iteratorは変数ではなく型ですよ」と明示する必要があるようです。
ちなみに、g++でうまくいかなかったらBCCでエラーを再現しているのですが、
こっちではすんなり通りました(警告すらでない)。
生成される実行形式だけでなく、言語仕様(の再現度)もコンパイラによって異なるのですね。
C++って面白いというか奥深いというか……。
出力結果:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97