0

As a C++ new learner, when I tried to learn about the template and iterator of C++, I wrote a function to check whether a number is amoung an array by using template and iterator of C++. The code is below:

template<typename T> bool find(vector<T>::iterator &begin, vector<T>::iterator &end, T target){
  for(;begin != end; begin++){
      if(*begin == target){
          return true;
      }
  }
  return false;
}


int main(void){
    vector<int> array{1,2,3,4,6,7};
    if(find(array.begin(),array.end(), 7)){
        cout << "find!";
    }
    else{
        cout << "not found!";
    }
} 

When I run the code above, I'll encouter the error, like this:

 template<typename T> bool find(vector<T>::iterator &begin, vector<T>::iterator &end, T target){
                                                                                        ^~~~~~
test.cpp:2631:94: error: expression list treated as compound expression in initializer [-fpermissive]
 template<typename T> bool find(vector<T>::iterator &begin, vector<T>::iterator &end, T target){
                                                                                              ^
test.cpp:2631:95: error: expected ';' before '{' token
 template<typename T> bool find(vector<T>::iterator &begin, vector<T>::iterator &end, T target){
                                                                                               ^
                                                                                               ;
test.cpp: In function 'int main()':
test.cpp:2643:8: error: reference to 'find' is ambiguous
     if(find(array.begin(),array.end(), 7)){
        ^~~~
In file included from C:/LLVM/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/algorithm:62,
                 from test.cpp:3:
C:/LLVM/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:3897:5: note: candidates are: 'template<class _IIter, class _Tp> _IIter std::find(_IIter, _IIter, const _Tp&)'
     find(_InputIterator __first, _InputIterator __last,
     ^~~~
In file included from C:/LLVM/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_facets.h:48,
                 from C:/LLVM/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/basic_ios.h:37,
                 from C:/LLVM/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:44,
                 from C:/LLVM/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,
                 from C:/LLVM/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,
                 from test.cpp:1:
C:/LLVM/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/streambuf_iterator.h:368:5: note:                 'template<class _CharT2> typename __gnu_cxx::__enable_if<std::__is_char<_CharT2>::__value, std::istreambuf_iterator<_CharT> >::__type std::find(std::istreambuf_iterator<_CharT>, std::istreambuf_iterator<_CharT>, const _CharT2&)'
     find(istreambuf_iterator<_CharT> __first,
     ^~~~
test.cpp:2631:43: note:                 'template<class T> bool find<T>'
 template<typename T> bool find(vector<T>::iterator &begin, vector<T>::iterator &end, T target){
                                           ^~~~~~~~

I just don't know what is wrong with the function and sincerely hope somebody can help!

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 3
    You should pass iterator by value. – 康桓瑋 Jan 12 '22 at 12:46
  • 5
    You almost certainly have a `using namespace std;` in your code, causing a name clash with `std::find` – UnholySheep Jan 12 '22 at 12:48
  • 2
    You need `typename vector::iterator begin` and `typename vector::iterator end`. (Templates are not beginner-friendly, by the way.) – molbdnilo Jan 12 '22 at 12:55
  • I actually wouldn't pass iterators at all but a `const` reference to the vector and use the proper functions to access its first/last element – Odysseus Jan 12 '22 at 13:01
  • That's [one of the reasons why `using namespace std` is bad practice](https://stackoverflow.com/q/1452721/995714) – phuclv Jan 12 '22 at 13:05
  • The code does not compile. Appears to be missing `#include ` and `#include ` and `using std::cout;` and `using std::vector`. And hopefully does not have `using namespace std;`. – Eljay Jan 12 '22 at 13:15
  • If you are taking the iterators by reference to use the found element, you could use `std::find` instead. – Caleth Jan 12 '22 at 13:16

1 Answers1

0

You should add typename before iterator type in function arguments. Also if you use the name find for your function and include std namespace in your code, there will be a clash. So you should use another name for the function or use scope resolution operator for std functions. Here I fixed it for you:

template<typename T>
bool findElement(typename std::vector<T>::iterator &begin, 
                 typename std::vector<T>::iterator &end, T target){
  for(;begin != end; begin++){
      if(*begin == target){
          return true;
      }
  }
  return false;
}


int main(void){
    std::vector<int> array{1,2,3,4,6,7};
    auto it1 = array.begin();
    auto it2 = array.end();
    if(findElement(it1, it2, 7)){
        std::cout << "find!";
    }
    else{
        std::cout << "not found!";
    }
}
Hamed
  • 36
  • 5