关于stackoverflow的第一个问题:)我对C ++比较新,并且从未使用过模板,所以请原谅我,如果我做的事情很愚蠢。我有一个模板函数,它梳理一个列表并检查一般类型的指定元素。这样我就可以指定它是在寻找一个字符串,还是一个int,或者其他什么。
template <class T>
bool inList(T match, std::string list)
{
int listlen = sizeof(list);
for (int i = 0; i <= listlen; i++) {
if (list[i] == match) return true;
else continue;
}
return false;
};
这是我对inList()
的电话。 testvec
是一个包含少量元素的字符串向量,包括&#34; test&#34;:
if (inList<string>("test", testvec))
cout << "success!";
else cout << "fail :(";
令我沮丧和困惑,在编译时,我被以下错误打了一遍:
error: no matching function for call to 'inList(const char [5], std::vector<std::basic_string<char> >&)'
我做错了什么? :(
[编辑] 我忽略了提到模板定义在全局命名空间中。 (它是一个简单的测试程序,看看我的模板是否可行,但它没有,显然:()
答案 0 :(得分:4)
那是因为没有办法从std :: vector转换为std :: string。相反,你需要做的是抽象集合的概念。
您这样做是为了让人们可以传入他们想要的任何收藏类型。他们可以使用数组,向量,字符串,列表,双端队列......只要它符合“概念”的要求即可。集合(这里是希望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());
如果我犯了错误,抱歉,我现在没有让我的编译器运行......