template <class T> class ObjectPool { public: using DeleterType = std::function<void(T*)>; void add(std::unique_ptr<T> t) { std::lock_guard<std::mutex> locker(mutex_); pool_.push_back(std::move(t)); } std::unique_ptr<T, DeleterType> get() { std::lock_guard<std::mutex> locker(mutex_); if (pool_.empty()) { cout << "no more object" << endl; return nullptr; } //every time add custom deleter for default unique_ptr std::unique_ptr<T, DeleterType> ptr(pool_.back().release(), [this](T* t) { pool_.push_back(std::unique_ptr<T>(t)); }); pool_.pop_back(); return std::move(ptr); } bool empty() { std::lock_guard<std::mutex> locker(mutex_); return pool_.empty(); } size_t size() { std::lock_guard<std::mutex> locker(mutex_); return pool_.size(); } private: std::mutex mutex_; std::vector<std::unique_ptr<T>> pool_; };