2008-10-06 8 views
9

Est-il possible de créer un conteneur de type STL, ou même simplement un itérateur de type STL, pour un ensemble existant d'éléments de type POD? Par exemple, supposons que j'ai un tableau d'ints. Il serait commode de pouvoir appeler certaines des fonctions STL, telles que find _ if, compter _ si, ou trier directement sur ce tableau.STL wrapper sans copie autour d'un tableau existant?

Non-solution: copie de l'ensemble de la matrice, ou même seulement des références aux éléments. L'objectif est d'économiser beaucoup de mémoire et de gagner du temps tout en permettant, espérons-le, l'utilisation d'autres algorithmes STL.

+0

" Par exemple, supposons que j'ai un tableau d'ints, il serait commode de pouvoir appeler certaines des fonctions STL, telles que find_if, count_if, ou trier directement sur ce tableau. " Vous pouvez. Tout ce qui précède. – moswald

Répondre

22

Vous pouvez appeler beaucoup d'algorithmes STL directement sur un tableau de type C normal - ils ont été conçus pour que cela fonctionne. par exemple,:

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

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

Je pense que vous trouverez que la plupart des choses fonctionnent comme vous vous y attendez.

+0

Bon à savoir! Je vous remercie. – Tyler

4

Vous pouvez utiliser Boost.Array pour créer un type de tableau C++ avec une sémantique STL.

tableaux en utilisant:

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

utilisant boost.arrays:

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

Mise à jour: Avec 11 C++, vous pouvez maintenant utiliser std::array.

+1

boost.array n'est pas zéro-copy – Bklyn

+2

Je ne voulais pas le copier dans un boost.array mais utiliser un boost.array comme objet original. – Ferruccio

5

Tous les algorithmes STL utilisent des itérateurs.
Un pointeur est un itérateur valide dans un tableau d'objets.

N.B. L'itérateur de fin doit être un élément après la fin du tableau. D'où les données + 5 dans le code suivant.

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

Un pointeur est un modèle valide d'un itérateur:

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

Vous pouvez utiliser un modèle de fonction en ligne de sorte que vous ne devez pas dupliquer l'index du tableau

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