POD 型の要素の既存の配列に対して、STL のようなコンテナー、または単に STL スタイルのイテレーターを作成することは可能ですか?
たとえば、int の配列があるとします。この配列に対して、find_if、count_if、または sort などの STL 関数を直接呼び出せると便利です。
非解決策: 配列全体をコピーするか、要素への参照だけをコピーします。目標は、メモリと時間を大幅に節約しながら、できれば他の STL アルゴリズムを使用できるようにすることです。
STL アルゴリズムの多くは、通常の C スタイルの配列で直接呼び出すことができます。これらは、これが機能するように設計されています。例えば、:
int ary[100];
// init ...
std::sort(ary, ary+100); // sorts the array
std::find(ary, ary+100, pred); find some element
ほとんどのものが期待どおりに機能することがわかると思います。
すべての STL アルゴリズムは反復子を使用します。
ポインターは、オブジェクトの配列への有効な反復子です。
注意: 終了イテレータは、配列の末尾の 1 つ後ろの要素でなければなりません。したがって、次のコードでは data+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"));
}
配列インデックスを複製する必要がないように、インライン関数テンプレートを使用できます
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);
}
Boost.Arrayを使用して、STL セマンティクスを持つ C++ 配列型を作成できます。
配列の使用:
int a[100];
for (int i = 0; i < 100; ++i)
a[i] = 0;
boost.arrays の使用:
boost::array<int,100> a;
for (boost::array<int,100>::iterator i = a.begin(); i != a.end(); ++i)
*i = 0;
更新: C++11 では、 を使用できるようになりstd::array
ました。
ポインターはイテレーターの有効なモデルです。
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;
}