あなたはそれを自分で書きました:
...これが、STLアルゴリズムが通常、メモリの割り当てを避け、代わりに渡されるようにする理由です。
ただし、STL アルゴリズムは通常「メモリを渡す」必要はなく、代わりにイテレータを操作します。これは特に、コンテナからアルゴリズムを分離するためのものであり、次の結果をもたらします。
オプション 8
入力イテレータを返すことにより、値の生成をそれらの値の使用と保存の両方から切り離します。
最も簡単な方法は を使用することboost::function_input_iterator
ですが、スケッチ メカニズムを以下に示します (主に、考えるよりも速く入力していたためです)。
入力反復子の型
(C++11 を使用しますが、std::function
を関数ポインターに置き換えるか、生成ロジックをハードコーディングすることができます):
#include <functional>
#include <iterator>
template <typename T>
class Generator: public std::iterator<std::input_iterator_tag, T> {
int count_;
std::function<T()> generate_;
public:
Generator() : count_(0) {}
Generator(int count, std::function<T()> func) : count_(count)
, generate_(func) {}
Generator(Generator const &other) : count_(other.count_)
, generate_(other.generate_) {}
// move, assignment etc. etc. omitted for brevity
T operator*() { return generate_(); }
Generator<T>& operator++() {
--count_;
return *this;
}
Generator<T> operator++(int) {
Generator<T> tmp(*this);
++*this;
return tmp;
}
bool operator==(Generator<T> const &other) const {
return count_ == other.count_;
}
bool operator!=(Generator<T> const &other) const {
return !(*this == other);
}
};
ジェネレータ関数の例
(繰り返しになりますが、ラムダを C++98 の行外関数に置き換えるのは簡単ですが、これはタイピングが少なくて済みます)
#include <random>
Generator<int> begin_random_integers(int n) {
static std::minstd_rand prng;
static std::uniform_int_distribution<int> pdf;
Generator<int> rv(n,
[]() { return pdf(prng); }
);
return rv;
}
Generator<int> end_random_integers() {
return Generator<int>();
}
使用例
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
using namespace std;
vector<int> out;
cout << "copy 5 random ints into a vector\n";
copy(begin_random_integers(5), end_random_integers(),
back_inserter(out));
copy(out.begin(), out.end(),
ostream_iterator<int>(cout, ", "));
cout << "\n" "print 2 random ints straight from generator\n";
copy(begin_random_integers(2), end_random_integers(),
ostream_iterator<int>(cout, ", "));
cout << "\n" "reuse vector storage for 3 new ints\n";
out.clear();
copy(begin_random_integers(3), end_random_integers(),
back_inserter(out));
copy(out.begin(), out.end(),
ostream_iterator<int>(cout, ", "));
}