私はクラスをレイジーなコンテナのように振る舞い、その場で値を生成します。その後、場合によっては値をフィルタリングしたいと思います。 Boost :: range :: adapters :: filteredはよく適しているようです。ただし、「範囲」への参照は保持されず、開始/終了イテレータのみが格納されます。boost :: filtersの範囲の寿命を延ばす
次のコードは、私のユースケースを模倣します。しかし、それは動作しません:container
は、r
が使用される前に破壊されます。
#include <iostream>
#include <vector>
#include <boost/range/adaptor/filtered.hpp>
#define PING() std::cerr << __PRETTY_FUNCTION__ << '\n'
using ints = std::vector<int>;
struct container
{
container() { PING(); }
~container() { PING(); }
using value_type = typename ints::value_type;
using iterator = typename ints::iterator;
using const_iterator = typename ints::const_iterator;
iterator begin() { PING(); return std::begin(c_); }
iterator end() { PING(); return std::end(c_); }
const_iterator begin() const { PING(); return std::cbegin(c_); }
const_iterator end() const { PING(); return std::cend(c_); }
ints c_ = { 1, 2, 3, 4, 5 };
};
int main()
{
auto r = container{} | boost::adaptors::filtered([](auto&& v) { return v % 2; });
std::cerr << "Loop\n";
for (auto i: r)
std::cout << i << '\n';
}
それは(live code)になり:
container::container()
const_iterator container::begin() const
const_iterator container::end() const
const_iterator container::end() const
const_iterator container::end() const
container::~container()
Loop
1
3
5
はみんながいる限り、私はそれを必要と住んでいることを保証するための簡単な方法はありますか?もちろんmain
で変数を宣言してcontainer{}
を格納することはできますが、実際にはこのコンテナが実際にはいくつかのオブジェクトを照会することで得られる実際の使用には不十分です。私はクライアント側がこれに対処しなければならないとは思わない。
範囲のコピーを保持するfiltered
のいくつかのバージョンを書き直すのが最も簡単なようですが、あまりにも多くのコードを書き込まないようにするソリューションを探したいと思います。そして、私はRange-v2のソリューションを本当に探しています。Range-v3に依存するのは早すぎるかもしれません。
コンテナの移動によってイテレータが無効になっていますか?そうでない場合は、これは簡単です。 – Yakk
@Yakkコンテナを別のコンテナに移動するとどういう意味ですか?はい、それはイテレータを無効にします。それらは実際にはポインタのようなイテレータであり、インデックスではありません。 – akim
ほとんどのコンテナは 'std :: array'と似ていません。他のコンテナへの' std :: move'がイテレータを動かすという点で、 'std :: vector'と似ています。そしてそれへのポインタ。 – Yakk