Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++, how to write a function so that it can work on any data type?

Tags:

c++

iterator

stl

I am learning C++ STL using this resource : http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=standardTemplateLibrary

The following function to reverse elemens of an array is given there :

template<typename T> void reversearr(T *begin, T *end) { 
      // We should at first decrement 'end' 
      // But only for non-empty range 
      if(begin != end) 
      { 
           end--; 
           if(begin != end) { 
                while(true) { 
                     swap(*begin, *end); 
                     begin++; 
                     if(begin == end) { 
                          break; 
                     } 
                     end--; 
                     if(begin == end) { 
                          break; 
                     } 
                } 
           } 
      } 
 } 

It works on system-defined types arrays such as:

int arr[]={1,2,3,4,5}
reversearr(arr,arr+5);

But it gives the following compiler error:

"Iterator02_ReverseIterators.cpp:39:32: error: no matching function for call to 'reversearr(std::vector::iterator, std::vector::iterator)'"

if I use this code:

vector<int> v;
//Code to insert data in vector
reversearr(v.begin(),v.end());

How to write the similar functions so that they can work on iterators too?

like image 243
user2916888 Avatar asked Dec 06 '22 23:12

user2916888


2 Answers

Welp, cppreference.com again has a full answer for us, also known as std::reverse:

Possible implementation:

template<class BidirIt>
void reverse(BidirIt first, BidirIt last)
{
    while ((first != last) && (first != --last)) {
        std::iter_swap(first++, last);
    }
}

Where BidirIt is a concept of a bidirectional iterator type. Both standard library containers' iterators and raw pointers satisfy it, that's why it works.

like image 89
Bartek Banachewicz Avatar answered Dec 31 '22 02:12

Bartek Banachewicz


In your code, the parameter is the pointer of T. When you use an iterator, the parameter is the pointer to an iterator, so it doesn't work.

If you want it to work with iterators, I think you should write like this:

template<typename T> 
void reversearr(T begin, T end)
{
   ...
}
like image 39
wangxf Avatar answered Dec 31 '22 01:12

wangxf