模板功能给出“呼叫无匹配功能".错误 [英] Template function gives "no matching function for call" error

查看:53
本文介绍了模板功能给出“呼叫无匹配功能".错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于stackoverflow的第一个问题:)我对C ++相对较新,并且从未使用过模板,因此,如果我做一些愚蠢的事情,请原谅我.我有一个模板功能,可以梳理列表并检查常规类型的指定元素.这样,我可以指定是要查找字符串还是int或其他内容.

First question on stackoverflow :) I'm relatively new to C++, and have never used templates, so forgive me if I'm doing something silly. I have a template function that combs through a list and checks for a specified element of a general type. That way I can specify whether it's looking for a string, or an int, or whatever.

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 是一个包含一些元素的字符串向量,包括"test":

This is my call to inList(). testvec is a string vector with a few elements, including "test":

if (inList<string>("test", testvec))
    cout << "success!";
else cout << "fail :(";

令我沮丧和困惑的是,在编译时,我被以下错误打了掌:

To my dismay and confusion, upon compiling, I am slapped with the following error:

error: no matching function for call to 'inList(const char [5], std::vector<std::basic_string<char> >&)'

我做错了什么?:(

我忽略了提及模板定义在全局名称空间中.(这是一个简单的测试程序,用于查看我的模板是否可以正常工作,而显然::)

I neglected to mention that the template definition is in the global namespace. (it's a simple test program to see if my template will work, and it does not, apparently :( )

推荐答案

这是因为无法将std :: vector转换为std :: string.相反,您需要做的是对集合概念进行抽象处理.

That's because there is no way to convert from a std::vector to a std::string. Instead, what you need to do is abstract over the concept of a collection.

您这样做是为了使人们可以传递他们想要的任何集合类型.他们可以使用数组,向量,字符串,列表,双端队列...,只要它适合集合的概念"(这就是希望c ++ 1x附带概念!).他们甚至可以使用自己的内部特别优化的收藏类型.这就是模板的美.

You do this so that people can pass in any collection type they want. They can use an array, a vector, a string, a list, a deque... as long as it fits the 'concept' of a collection (here's to hoping c++1x comes with concepts!). They can even use their own in-house specially optimized collection types. That's the beauty of templates.

使用C ++ 11(可与任何标准集合,原始数组和用户定义的类型一起使用):

Using C++11 (works with any standard collection, primitive arrays, and user-defined types):

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推导为模板参数的非标准扩展,因此请提供显式覆盖:

It's a non-standard extension to deduce std::initializer_list as a template argument, so provide an explicit override:

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;
}

使用此版本,您可以将其命名为:

With this version, you can call it like:

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的我们来说,这将适用于字符串和向量以及某些用户定义的类型.不过,它不适用于原始数组.

And for those of us still in C++98, this will work for both strings and vectors, and some user-defined types. It will not work with raw arrays though.

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样式:

Or, you can go STL style:

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());

如果我犯了一个错误,对不起,我现在没有正在运行我的编译器...

If I made a mistake, sorry, I don't have my compiler running right now...

这篇关于模板功能给出“呼叫无匹配功能".错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆