これは、std::vector から std::string に変換する方法がないためです。代わりに、コレクションの概念を抽象化する必要があります。
これを行うことで、ユーザーは任意のコレクション タイプを渡すことができます。コレクションの「概念」に適合する限り、配列、ベクトル、文字列、リスト、deque を使用できます (ここでは、c++1x に概念が付属していることを願っています)。社内で特別に最適化された独自のコレクション タイプを使用することもできます。それがテンプレートの美しさです。
C++11 を使用する (すべての標準コレクション、プリミティブ配列、およびユーザー定義型で動作します):
template<class elem_t, class list_t>
bool in_list(const elem_t& elem, const list_t& list) {
for (const auto& i : list) {
if (elem == i) {
return true;
}
}
return false;
}
編集: std::initializer_list をテンプレート引数として推測するのは非標準の拡張であるため、明示的なオーバーライドを提供します。
template<class elem_t>
bool in_list(const elem_t& elem, std::initializer_list<elem_t> list) {
for (const auto& i : list) {
if (elem == i) {
return true;
}
}
return false;
}
このバージョンでは、次のように呼び出すことができます。
int main() {
std::vector<int> a = {1, 2, 3, 4, 5};
std::cout << in_list(3, a) << std::endl;
std::string b = "asdfg";
std::cout << in_list('d', b) << std::endl;
std::cout << in_list('d', "asdfg") << std::endl;
std::cout << in_list(3, {1, 2, 3, 4, 5}) << std::endl;
return 0;
}
そして、まだ C++98 を使用している私たちにとって、これは文字列とベクトルの両方、および一部のユーザー定義型で機能します。ただし、生の配列では機能しません。
template<class elem_t, class list_t>
bool in_list_98(const elem_t& elem, const list_t& list) {
list_t::const_iterator end = list.end(); //prevent recomputation of end each iteration
for (list_t::const_iterator i = list.begin(); i < end; ++i) {
if (elem == *i) {
return true;
}
}
return false;
}
または、STL スタイルにすることもできます。
template<class elem_t, class iterator_t>
bool in_list_stl(const elem_t& elem, iterator_t begin, iterator_t end) {
for (iterator_t i = begin; i < end; ++i) {
if (elem == *i) {
return true;
}
}
return false;
}
//call like std::string s = "asdf"; in_list_stl('s', s.begin(), s.end());
間違いを犯した場合は、申し訳ありませんが、現在コンパイラを実行していません...