I have written a very simple wrapper around std::shared_ptr
that supports lazy initialization. Do you see any problems?
#include <functional>
#include <tuple>
#include <utility>
template <class T, typename ... Args>
class LazySharedPtr {
public:
LazySharedPtr(Args ... args) :
ptr(nullptr) {
this->init = (args = std::make_tuple(std::forward<Args>(args) ...))() mutable {
return std::apply(()(auto&& ... args) {
return std::make_shared<T>(std::forward<Args>(args) ...);
}, std::move(args));
};
}
virtual ~LazySharedPtr() = default;
bool IsInited() const noexcept {
return ptr != nullptr;
}
void Init() {
this->InitAndGet();
}
std::shared_ptr<T> Get() {
return (ptr) ? ptr : InitAndGet();
}
const std::shared_ptr<T> Get() const {
return (ptr) ? ptr : InitAndGet();
}
T* operator ->() {
return this->Get().get();
}
const T* operator ->() const {
return this->Get().get();
}
explicit operator bool() const noexcept {
return this->IsInited();
}
protected:
std::function<std::shared_ptr<T>()> init;
mutable std::shared_ptr<T> ptr;
std::shared_ptr<T> InitAndGet() const {
ptr = this->init();
return ptr;
}
};
Note: Visual Studio report warning for this->Get().get()
:
Warning C26815 The pointer is dangling because it points at a
temporary instance which was destroyed.
However, I dont see why, because shared_ptr is owned by the class so there should alway be at least one instance “alive”. Imho, This warning is not reported by compiler, only by Intellisense.