24 июля 2007

Boost.ForEach and rvalue [2]

По поводу использования rvalue-(proxy)контейнеров в Boost.ForEach: Eric Niebler, создатель этой библиотеки, пояснил мне, что намерено выбрал использование const_iterator-ов для rvalue объектов, чтобы предотвратить ненамеренное изменение контейнеров, возвращенных как rvalue. Что касается proxy-контейнеров, таких как boost::iterator_range, то Эрик предлагает приравнять в них константные итераторы к обычным, так как изменение самого прокси-контейнера не происходит. Цитирую:

The interface I chose preserves object lifetimes and prevents inadvertent mutation of temporary objects. Weakening its guarantees is a bad idea.

If you want the proxy to offer either a const or mutable interface *and* you want our proxy to work with BOOST_FOREACH, you should base it on the const-ness or mutability of the object being proxied, not the constness of the proxy itself. Consider:
template<class Range>
struct proxy {
typedef typename range_result_iterator<Range>::type iterator;
typedef typename range_result_iterator<Range>::type const_iterator;
iterator begin() const { return boost::begin(rng_); }
iterator end() const { return boost::end(rng_); }
// etc ...
Range &rng_;
};
Now, you can have const and mutable proxied objects like:
// ok, a mutable proxy
proxy< std::vector<int> > p1;

// ok, still a mutable proxy
proxy< std::vector<int> > const p2;

// ok, a const proxy
proxy< std::vector<int> const > p3;

// still a const proxy
proxy< std::vector<int> const > const p4;

Комментариев нет: