Question

Is it possible to create an STL-like container, or even just an STL-style iterator, for an existing array of POD-type elements?

For example, suppose I have an array of ints. It would be convenient to be able to call some of the STL functions, such as find_if, count_if, or sort directly on this array.

Non-solution: copying the entire array, or even just references to the elements. The goal is to be very memory- and time-saving while hopefully allowing use of other STL algorithms.

Was it helpful?

Solution

You can call many of the STL algorithms directly on a regular C style array - they were designed for this to work. e.g.,:

int ary[100];
// init ...

std::sort(ary, ary+100); // sorts the array
std::find(ary, ary+100, pred); find some element

I think you'll find that most stuff works just as you would expect.

OTHER TIPS

You can use an inline function template so that you don't have to duplicate the array index

template <typename T, int I>
inline T * array_begin (T (&t)[I])
{
  return t;
}

template <typename T, int I>
inline T * array_end (T (&t)[I])
{
  return t + I;
}

void foo ()
{
  int array[100];
  std::find (array_begin (array)
      , array_end (array)
      , 10);
}

All the STL algorithms use iterators.
A pointer is a valid iterator into an array of objects.

N.B.The end iterator must be one element past the end of the array. Hence the data+5 in the following code.

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

int main()
{
    int   data[] = {4,3,7,5,8};
    std::sort(data,data+5);

    std::copy(data,data+5,std::ostream_iterator<int>(std::cout,"\t"));
}

You can use Boost.Array to create a C++ array type with STL semantics.

using arrays:

int a[100];
for (int i = 0; i < 100; ++i)
    a[i] = 0;

using boost.arrays:

boost::array<int,100> a;
for (boost::array<int,100>::iterator i = a.begin(); i != a.end(); ++i)
    *i = 0;

Update: With C++11, you can now use std::array.

A pointer is a valid model of an iterator:

struct Bob
{ int val; };

bool operator<(const Bob& lhs, const Bob& rhs)
{ return lhs.val < rhs.val; }

// let's do a reverse sort
bool pred(const Bob& lhs, const Bob& rhs)
{ return lhs.val > rhs.val; }

bool isBobNumberTwo(const Bob& bob) { return bob.val == 2; }

int main()
{
    Bob bobs[4]; // ok, so we have 4 bobs!
    const size_t size = sizeof(bobs)/sizeof(Bob);
    bobs[0].val = 1; bobs[1].val = 4; bobs[2].val = 2; bobs[3].val = 3;

    // sort using std::less<Bob> wich uses operator <
    std::sort(bobs, bobs + size);
    std::cout << bobs[0].val << std::endl;
    std::cout << bobs[1].val << std::endl;
    std::cout << bobs[2].val << std::endl;
    std::cout << bobs[3].val << std::endl;

    // sort using pred
    std::sort(bobs, bobs + size, pred);
    std::cout << bobs[0].val << std::endl;
    std::cout << bobs[1].val << std::endl;
    std::cout << bobs[2].val << std::endl;
    std::cout << bobs[3].val << std::endl;

    //Let's find Bob number 2
    Bob* bob = std::find_if(bobs, bobs + size, isBobNumberTwo);
    if (bob->val == 2)
        std::cout << "Ok, found the right one!\n";
    else 
        std::cout << "Whoops!\n";

    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top