ecco un breve iteratore conto alla rovescia:
template<class F,
class T=std::result_of_t<F const&(std::size_t const&)>
>
struct countdown_iterator:
std::iterator<
std::input_iterator_tag,
T,
std::ptrdiff_t,
T*,
T
>
{
using self=countdown_iterator;
std::size_t count_down = 0;
F f;
T operator*() const {
return f(count_down);
}
self& operator++() {
--count_down;
return *this;
}
self operator++(int) {
auto result = *this;
++(*this);
return result;
}
friend bool operator==(self const& lhs, self const& rhs) {
return lhs.count_down == rhs.count_down;
}
friend bool operator!=(self const& lhs, self const& rhs) {
return !(lhs==rhs);
}
};
una classe gamma assed:
template<class It>
struct range {
It b, e;
It begin() const { return b; }
It end() const { return e; }
bool empty() const { return begin()==end(); }
decltype(auto) front() const { return *begin(); }
range():b(),e() {}
range(It s, It f):b(s), e(f) {}
range(range const&)=default;
range& operator=(range const&)=default;
~range() = default;
template<class C,
class=std::enable_if_t<!std::is_same<std::decay_t<C>, range>>
>
range(C&& c):
range(std::begin(std::forward<C>(c)), std::end(std::forward<C>(c)))
{}
};
template<class It>
range<It> make_range(It b, It e) { return {std::move(b),std::move(e)}; };
e poi possiamo contare:
template<class F,
class dF=std::decay_t<F>,
class It=countdown_iterator<dF>
class R=range<It>
>
R countdown(std::size_t N, F&& f) {
countdown_iterator e(N, f):
countdown_iterator b(N, std::forward<F>(f));
return {std::move(b),std::move(e)};
}
uso :
size_t n = 100;
size_t m = 1000;
auto src = countdown(
n,
[m](auto&&){ std::vector<foo> v; v.reserve(m); return v; }
);
std::vector<std::vector<foo>> v;
v.reserve(100);
v.insert(v.end(), src.begin(), src.end());
qui creiamo un iteratore conto alla rovescia "input" che corre per 100 iteratori. Ogni volta che lo si chiama, restituisce un vettore con la capacità m
.
Penso che dipenda molto da come andrete a popolare i vettori interni. – LogicStuff
@LogicStuff Potresti per favore chiarire un po '? –
"Voglio solo prenotare senza costruire perché foo è costoso da costruire due volte." - Non memorizzare 'foo's direttamente? Forse ['std :: unique_ptr'] (http://en.cppreference.com/w/cpp/memory/unique_ptr) o ['std :: experimental :: opzionale '] (http: // en. cppreference.com/w/cpp/experimental/optional). –
BoBTFish