#c #arrays #stl #iterator
Вопрос:
Можно ли создать контейнер, подобный STL, или даже просто итератор в стиле STL, для существующего массива элементов типа POD?
Например, предположим, что у меня есть массив int. Было бы удобно иметь возможность вызывать некоторые функции STL, такие как find_if, count_if или сортировать непосредственно в этом массиве.
Не решение: копирование всего массива или даже просто ссылок на элементы. Цель состоит в том, чтобы максимально сэкономить память и время, в то же время, надеюсь, позволяя использовать другие алгоритмы STL.
Комментарии:
1. «Например, предположим, что у меня есть массив int. Было бы удобно иметь возможность вызывать некоторые функции STL, такие как find_if, count_if или сортировать непосредственно в этом массиве.» Ты можешь. Все вышеперечисленное.
Ответ №1:
Вы можете вызывать многие алгоритмы STL непосредственно в обычном массиве в стиле C — они были разработаны для этой работы. например,:
int ary[100];
// init ...
std::sort(ary, ary 100); // sorts the array
std::find(ary, ary 100, pred); find some element
Я думаю, вы обнаружите, что большинство вещей работает именно так, как вы ожидали.
Ответ №2:
Вы можете использовать встроенный шаблон функции, чтобы не дублировать индекс массива
template <typename T, int I>
inline T * array_begin (T (amp;t)[I])
{
return t;
}
template <typename T, int I>
inline T * array_end (T (amp;t)[I])
{
return t I;
}
void foo ()
{
int array[100];
std::find (array_begin (array)
, array_end (array)
, 10);
}
Ответ №3:
Все алгоритмы STL используют итераторы.
Указатель является допустимым итератором в массив объектов.
N. B. Конечный итератор должен быть на один элемент дальше конца массива. Отсюда данные 5 в следующем коде.
#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"));
}
Ответ №4:
Вы можете использовать Boost.Массив для создания типа массива C с семантикой STL.
использование массивов:
int a[100];
for (int i = 0; i < 100; i)
a[i] = 0;
использование boost.массивов:
boost::array<int,100> a;
for (boost::array<int,100>::iterator i = a.begin(); i != a.end(); i)
*i = 0;
Обновление: Теперь вы можете использовать C 11 std::array
.
Комментарии:
1. Я не имел в виду копировать его в boost.array, а использовать boost.array в качестве исходного объекта.
Ответ №5:
Указатель-это допустимая модель итератора:
struct Bob
{ int val; };
bool operator<(const Bobamp; lhs, const Bobamp; rhs)
{ return lhs.val < rhs.val; }
// let's do a reverse sort
bool pred(const Bobamp; lhs, const Bobamp; rhs)
{ return lhs.val > rhs.val; }
bool isBobNumberTwo(const Bobamp; 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;
}