誰もが言うように、C++ のベクトルは 1 つの型しか保持しません。各要素の型を順番にチェックする必要はありませんし、意味もありません。それを行う方法がないからです。代わりに行うことは、引数の型で関数をオーバーロードすることです。このようなもの:
string toCustomString(const string &str) {
return "foo" +str + "bar";
}
template <typename T>
string toCustomString(const std::vector<T> &vec) {
string ret;
for(size_t i = 0; i < vec.size(); ++i)
ret += toCustomString(vec[i]);
return ret;
}
ここで、誰かが avector<string>
を渡すtoCustomString
と、呼び出しはオーバーロードtoCustomString(vec[i])
を選択しますtoCustomString(const string &str)
。
誰かが avector<int>
を渡すと、 toCustomString
(現在)toCustomString(int)
オーバーロード[*] がないため、コードはコンパイルされません。
誰かが avector<vector<string>>
をに渡すと、toCustomString
次にa が渡されます。上記を参照してください。toCustomString(vec[i])
vector<string>
3 つのケースすべてで、異なる toCustomString
関数が呼び出されます。最初のケースは で、これは3 番目のケースとは異なるテンプレートtoCustomString<string>(const vector<string>&)
のインスタンス化です。中間のケースは をインスタンス化しようとしますが、知っているどの関数とも一致しないため失敗します。toCustomString
toCustomString<vector<string>>(const vector<vector<string>>&)
toCustomString<int>
toCustomString(v[i])
これらはすべてコンパイル時に決定されます。テンプレートのポイントは、それらの間に特定の違いがある複数の関数 (またはクラス) を作成することです。この場合の違いは、渡されるベクトルのタイプです。
[*] これは、3 番目のオプションではなく、ベクトルまたはvec[i]
文字列でなければならないというあなたの主張と一致しているようです。たとえば、 a の戻り値を空にしたい場合は、キャッチオール テンプレートを追加できます。vector<something_else>
template <typename T>
string toCustomString(const T &) {
return string();
}
もちろん、処理したい他の型にオーバーロードを追加することもできます。