テンプレートの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