同様のタイプのコンテンツを印刷するためのジェネリック関数を定義したいと思いstd::map
ます。私の最初の試みは次のような関数です:
template <class K, class V>
inline void PrintCollection(const std::map<K,V>& map,
const char* separator="\n",
const char* arrow="->",
const char* optcstr="") {
typedef typename std::map<K,V>::const_iterator iter_type;
std::cout << optcstr;
for (iter_type begin = map.begin(), it = begin, end = map.end();
it != end; ++it) {
if (it != begin) {
std::cout << separator;
}
std::cout << it->first << arrow << it->second;
}
std::cout << std::endl;
}
これは正常に動作します。この関数をもう1つのステップで一般化しようとすると、つまりstd::multimap
型に対して機能するようにすると、コンパイラーは怒ります。std::map
関数定義でジェネリックにするいくつかの方法を試しました。たとえば、次のようになります。
template <class M, class K, class V>
inline void PrintCollection(const M<K,V>& map,
const char* separator="\n",
const char* arrow="->",
const char* optcstr="") {
typedef typename M<K,V>::const_iterator iter_type;
std::cout << optcstr;
for (iter_type begin = map.begin(), it = begin, end = map.end();
it != end; ++it) {
if (it != begin) {
std::cout << separator;
}
std::cout << it->first << arrow << it->second;
}
std::cout << std::endl;
}
成功しませんでした。
上で定義したように、この関数を一般化するにはどうすればよいですか?
より明確にするために、私はすでにこの関数の前に定義されたベクトルのようなクラスに対して定義された関数を持っています。のような
template <class T>
inline void PrintCollection(const T& collection,
const char* separator="\n",
const char* optcstr="") {
typedef typename T::const_iterator iter_type;
std::cout << optcstr;
for (iter_type begin = collection.begin(), it = begin, end = collection.end();
it != end;
++it) {
if (it != begin) {
std::cout << separator;
}
std::cout << *it;
}
std::cout << std::endl;
}
それで、この関数をマップのようなクラスに特化させるためにそれを達成したいと思います。私はC++にかなり慣れていないので、この種のものの正確な用語はわかりません。これは「テンプレートの特殊化」と呼ばれますか?