STL iterator traitor
反復器の型別(associated types)は汎用プログラミングでよく用いられる技術である.C++は弱い言語であるためtypeof()はサポートされていない.RTTIのtypeid()は使用できますが、得られるのは型別の名前であり、変数の宣言には使用できません.
解決策はテンプレート関数のパラメータで倒すことができる(argument deducation)
しかし,反復器の型別は必ずしも反復器自身の型を指すものではない.したがって,上記の方法ではすべての問題を解決することはできない.
インライン宣言を使用できます
これは偏特化(Partial Specialization)が必要です
解決策はテンプレート関数のパラメータで倒すことができる(argument deducation)
#include<iostream>
using namespace std;
template<class I, class T>
void func_impl(I iter, T t)
{
T tmp;
tmp = *iter;
cout<<tmp<<endl;
//do something ...
}
template<class I>
void func(I iter)
{
func_impl(iter, *iter);
}
int main()
{
int i = 10;
func(&i);
}
しかし,反復器の型別は必ずしも反復器自身の型を指すものではない.したがって,上記の方法ではすべての問題を解決することはできない.
インライン宣言を使用できます
#include<iostream>
#include<string>
#include<vector>
using namespace std;
template<class T>
struct MyIter {
typedef T value_type;
T* ptr;
MyIter(T* p): ptr(p) {}
T& operator* () const { return *ptr; }
};
template<class T>
typename my_iterator_traits<T>::value_type
func(T iter)
{ return *iter; }
int main()
{
MyIter<int> iter(new int(10));
}
しかし、すべての反復器がclassタイプであるわけではありません.ポインタの場合、上記の方法は機能しません.私たちは彼のclass typeを定義できないからです.これは偏特化(Partial Specialization)が必要です
#include<iostream>
#include<string>
#include<vector>
using namespace std;
template<class T>
struct MyIter {
typedef T value_type;
T* ptr;
MyIter(T* p): ptr(p) {}
T& operator* () const { return *ptr; }
};
template<class T>
struct my_iterator_traits{
typedef typename T::value_type value_type;
};
template<class T>
struct my_iterator_traits<T*>{
typedef T value_type;
};
template<class T>
typename my_iterator_traits<T>::value_type
func(T iter)
{ return *iter; }
int main()
{
MyIter<int> iter(new int(10));
int p = 16;
cout<<func(&p)<<endl;
}