zahmati
zahmati

Reputation: 1291

c++ general int array and vector iterator

In the following code, I need to define an iterator which can iterate on both vector<int> and int[100]. How to define mi here?

template<class arraytype>
void array_show(arraytype array, size_t arraySize)
{
    // how to define mi????
    for (mi = array; array != m.end(); array++)
        std::cout << " " << *mi << std::endl;
}

Upvotes: 0

Views: 1273

Answers (4)

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

Try the following

#include <iostream>
#include <vector>
#include <iterator>

template<class arraytype>
void array_show( const arraytype &array )
{
    for ( const auto &x : array ) std::cout << x << ' ';
    std::cout << std::endl;
}

int main() 
{
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    std::vector<int> v( std::begin( a ), std::end( a ) );

    array_show( a );
    std::endl( std::cout );

    array_show( v );
    std::endl( std::cout );

    return 0;
}

The program output is

1 2 3 4 5 6 7 8 9 10 

1 2 3 4 5 6 7 8 9 10 

Another approach is to use iterators. For example (Here are shown the both function definitions)

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

template<class arraytype>
void array_show( const arraytype &array )
{
    for ( const auto &x : array ) std::cout << x << ' ';
    std::cout << std::endl;
}

template <class InputIterator>
void array_show( InputIterator first, InputIterator last )
{
    typedef typename std::iterator_traits<InputIterator>::value_type value_type;
    std::copy( first, last, 
               std::ostream_iterator<value_type>( std::cout, " ") );

    std::cout << std::endl;     
}

int main() 
{
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    std::vector<int> v( std::begin( a ), std::end( a ) );

    array_show( std::begin( a ), std::end( a ) );
    std::endl( std::cout );

    array_show( std::begin( v ), std::end( v ) );
    std::endl( std::cout );


    return 0;
}

The program output is the same as above

1 2 3 4 5 6 7 8 9 10 

1 2 3 4 5 6 7 8 9 10 

Instead of the algorithm std::copy you can write a loop yourself. For example

template <class InputIterator>
void array_show( InputIterator first, InputIterator last )
{
    for ( ; first != last; ++first )
    {
        std::cout << *first << ' '; 
    }           

    std::cout << std::endl;     
}

Upvotes: 3

marcinj
marcinj

Reputation: 50026

Here is an example below. The importantpart is to use arraytype& - a reference, this way regular array is not decayed to pointer - this way it is possible to read its size inside array_show.

template<class arraytype>
void array_show(arraytype& array, size_t arraySize)
{
    // how to define mi????
    for (auto mi = std::begin(array); mi != std::end(array); mi++)
        std::cout << " " << *mi << std::endl;
}

Upvotes: 0

Mateusz Grzejek
Mateusz Grzejek

Reputation: 12088

If you need to use it the way you showed:

template<class arraytype>
void array_show(arraytype array, size_t arraySize)
{
    auto end = &(array[arraySize]);
    for (mi = &(array[0]); array != end; ++array)
        std::cout << " " << *mi << std::endl;
}

As vector has defined operator[], construct &(array[...]) will work for both vector and plain array.

But preferably:

template <class Iter>
void array_show(Iter begin, Iter end)
{
    for (Iter it = begin, it != end; ++it)
        std::cout << " " << *it << std::endl;
}

and then:

vector<int> vi;
int ai[100];
//fill with data

array_show(vi.begin(). vi.end());
array_show(ai, ai + 100);

Upvotes: 1

Abhijit
Abhijit

Reputation: 63767

Define your function to accept the start and the end iterators. You can then use your function for any form of iterables

template<typename Iter>
void array_show(Iter begin, Iter end)
{
    // how to define mi????
    for (Iter it = begin; it != end; it++)
        std::cout << " " << *it << std::endl;
}

You can then call your function as follows

int main(int argc, char *argv[]) {
    std::vector<int> vec= { 3, 1, 4, 1, 5, 9, 2, 6 };
    int arr[] = { 3, 1, 4, 1, 5, 9, 2, 6 };
    array_show(vec.begin(), vec.end());
    array_show(std::begin(arr), std::end(arr));


}

In case you would want to pass the array as a reference as well as a vector, you should create two different function overloads to support both. This probably looks like your intention as your function signature intended to accept the size as well as the object.

template<typename Ty, size_t size>
void array_show(Ty(&arr)[size])
{
    for (size_t i = 0; i < size; i++)
        std::cout << " " << arr[i] << std::endl;
}

and subsequently call it as

int arr[] = { 3, 1, 4, 1, 5, 9, 2, 6 };
array_show(arr);

Upvotes: 1

Related Questions