Pergunta

É possível criar um recipiente STL-like, ou mesmo apenas uma iteração de estilo STL, para uma matriz existente de elementos POD do tipo?

Por exemplo, suponha que eu tenho um array de inteiros. Seria conveniente para ser capaz de chamar algumas das funções STL, como find_if, count_if, ou classificar diretamente sobre essa matriz.

Não-solução: a cópia de toda a matriz, ou mesmo apenas referências aos elementos. O objetivo é ser muito memória- e enquanto esperamos permitindo o uso de outros algoritmos STL de economia de tempo.

Foi útil?

Solução

Você pode chamar muitos dos algoritmos de STL diretamente em uma matriz regular estilo C - eles foram projetados para que isso funcione. . Por exemplo,:

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

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

Eu acho que você verá que a maioria das coisas funciona exatamente como seria de esperar.

Outras dicas

Você pode usar um modelo de função em linha de modo que você não tem que duplicar o índice de array

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);
}

Todos os algoritmos STL usar iteradores.
Um ponteiro é um iterador válido em um array de objetos.

NB. O fim iteração deve ser um elemento para além da extremidade da matriz. Daí a dados + 5 no código a seguir.

#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"));
}

Você pode usar Boost.Array para criar um tipo de matriz ++ C com semântica STL.

usando matrizes:

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

usando boost.arrays:

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

Update:. Com C ++ 11, agora você pode usar std::array

Um ponteiro é um modelo válido de um iterador:

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;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top