Используя boost::optional
, вы можете получить такую вещь:
// 100 lazy BigStuffs
std::vector< boost::optional<BigStuff> > v(100);
v[49] = some_big_stuff;
Создаст 100 ленивых и присвоит одно действительное some_big_stuff
v[49]
. boost::optional
не будет использовать кучи памяти, но будет использовать размещения новые для создания объектов в буфере, выделенном стеком Я бы создал обертку вокруг boost::optional
вот так:
template<typename T>
struct LazyPtr {
T& operator*() { if(!opt) opt = T(); return *opt; }
T const& operator*() const { return *opt; }
T* operator->() { if(!opt) opt = T(); return &*opt; }
T const* operator->() const { return &*opt; }
private:
boost::optional<T> opt;
};
Это теперь использует boost::optional
для выполнения вещей. Он должен поддерживать конструкцию на месте, как эта (пример на op*
):
T& operator*() { if(!opt) opt = boost::in_place(); return *opt; }
Что не требует копирования. Однако текущее усиление не включает перегрузку оператора присваивания. Источник делает, однако. Я не уверен, является ли это просто дефектом руководства или его преднамеренно пропущена документация. Поэтому я бы использовал более безопасный способ, используя назначение копирования, используя T()
.