1

我有以下几行代码和编译错误。应该是我对模板函数的错误理解,或者c++泛型,或者别的什么。提前感谢您指出。

#include <iostream>
#include <vector>

using namespace std;

template <typename T>
T* find(vector<T> &vec, T value)
{
  vector<T>::iterator first = vec.begin();
  vector<T>::iterator last = vec.end();
  for(; first != last; first ++)
      if(*first == value)
          return first;
  return 0;
}

控制台中的编译错误

debug.cpp: In function ‘T* find(std::vector<T, std::allocator<_CharT> >&, T)’:
debug.cpp:9: error: expected `;' before ‘first’
debug.cpp:10: error: expected `;' before ‘last’
debug.cpp:11: error: ‘first’ was not declared in this scope
debug.cpp:11: error: ‘last’ was not declared in this scope
4

3 回答 3

5

最后你需要使用typename vector<T>::iterator first和类似的。否则编译器会发现声明不明确,因为它没有意识到这vector<T>::iterator是一种类型。它可以是成员函数或其他东西。从技术上讲,它们被称为dependent typenames(因为它们依赖于模板类型T。每次你有一个依赖类型时,都可以避免这样的头痛。有关更多详细信息,typename请参见例如http://pages.cs.wisc.edu/~driscoll/typename.html .

于 2014-04-26T02:19:28.860 回答
2

除了不包括typename由于类型名称依赖性而需要它的关键字之外,您还重新发明了其他人的算法,即std::find. 关于什么是类型名依赖以及它为什么需要解析,这个答案比我能更好地解释它。

而且您还将容器迭代器类型视为项目类型指针,这种做法适用于矢量,但如果您想使用迭代器是包装器而不是立即指针的不同容器,则会严重限制您的代码。

关于缩短代码以及解决typename问题:

template <typename T>
T* find(std::vector<T> &vec, const T& value)
{
    typename std::vector<T>::iterator it = std::find(vec.begin(), vec.end(), value);
    return (it != vec.end()) ? &(*it) : nullptr;
}

注意:对于 C++11,这可以避免auto

template <typename T>
T* find(std::vector<T> &vec, const T& value)
{
    auto it = std::find(vec.begin(), vec.end(), value);
    return (it != vec.end()) ? &(*it) : nullptr;
}
于 2014-04-26T02:28:26.713 回答
0

下面是一个工作版本,但仍然不清楚为什么原始帖子中的代码不正确。

#include <iostream>
#include <vector>

using namespace std;

template <typename IteratorType, typename T>
IteratorType find(IteratorType first, IteratorType last, T &value)
{
  for(; first != last; first ++)
      if (*first == value)
          return first;
  return last;
}
于 2014-04-26T02:10:19.870 回答