Я использую пул смарт-объектов в стиле RAII и хочу установить полученный объект как член другого класса.
Пул смарт-объектов, предложенный Т. C. :
template <class T, class D = std::default_delete<T>>
class SmartObjectPool
{
private:
struct ReturnToPool_Deleter {
explicit ReturnToPool_Deleter(std::weak_ptr<SmartObjectPool<T, D>* > pool) : pool_(pool) {
}
void operator()(T* ptr) {
if (auto pool_ptr = pool_.lock())
(*pool_ptr.get())->add(std::unique_ptr<T, D>{ptr});
else
D{}(ptr);
}
private:
std::weak_ptr<SmartObjectPool<T, D>* > pool_;
};
public:
using ptr_type = std::unique_ptr<T, ReturnToPool_Deleter >;
SmartObjectPool() : this_ptr_(new SmartObjectPool<T, D>*(this)) {}
virtual ~SmartObjectPool(){}
void add(std::unique_ptr<T, D> t) {
pool_.push(std::move(t));
}
ptr_type acquire() {
if (pool_.empty())
throw std::out_of_range("Cannot acquire object from an empty pool.");
ptr_type tmp(pool_.top().release(),
ReturnToPool_Deleter{
std::weak_ptr<SmartObjectPool<T, D>*>{this_ptr_}});
pool_.pop();
return std::move(tmp);
}
bool empty() const {
return pool_.empty();
}
size_t size() const {
return pool_.size();
}
private:
std::shared_ptr<SmartObjectPool<T, D>* > this_ptr_;
std::stack<std::unique_ptr<T, D> > pool_;
};
И класс Setter, для которого я хочу установить полученный объект как член другого класса (Setter):
class Setter {
public:
void setValue(SmartObjectPool<int>::ptr_type value) {
m_value = std::move(value);
}
private:
SmartObjectPool<int>::ptr_type m_value;
};
и основная реализация:
int main()
{
SmartObjectPool<int> pool;
pool.add(std::make_unique<int>());
assert(pool.size() == 1u);
{
auto obj = pool.acquire();
Setter setter;
setter.setValue(std::move(obj));
assert(pool.size() == 0u);
}
assert(pool.size() == 1u);
auto obj = pool.acquire();
return 0;
}
И я получил ошибку компиляции о конструкторе ReturnToPool_Deleter:
In file included from /usr/include/c++/5/functional:55:0,
from /usr/include/c++/5/memory:79,
from src/main.cpp:1:
/usr/include/c++/5/tuple: In instantiation of ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base() [with long unsigned int _Idx = 1ul; _Head = SmartObjectPool<int>::ReturnToPool_Deleter]’:
/usr/include/c++/5/tuple:353:15: required from ‘constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl() [with long unsigned int _Idx = 1ul; _Head = SmartObjectPool<int>::ReturnToPool_Deleter]’
/usr/include/c++/5/tuple:202:29: required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl() [with long unsigned int _Idx = 0ul; _Head = int*; _Tail = {SmartObjectPool<int>::ReturnToPool_Deleter}]’
/usr/include/c++/5/tuple:602:20: required from ‘constexpr std::tuple<_T1, _T2>::tuple() [with _T1 = int*; _T2 = SmartObjectPool<int>::ReturnToPool_Deleter]’
/usr/include/c++/5/bits/unique_ptr.h:158:14: required from ‘constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr() [with _Tp = int; _Dp = SmartObjectPool<int>::ReturnToPool_Deleter]’
src/main.cpp:59:7: required from here
/usr/include/c++/5/tuple:105:22: error: no matching function for call to ‘SmartObjectPool<int>::ReturnToPool_Deleter::ReturnToPool_Deleter()’
: _M_head_impl() { }
^
src/main.cpp:11:22: note: candidate: SmartObjectPool<T, D>::ReturnToPool_Deleter::ReturnToPool_Deleter(std::weak_ptr<SmartObjectPool<T, D>*>) [with T = int; D = std::default_delete<int>]
explicit ReturnToPool_Deleter(std::weak_ptr<SmartObjectPool<T, D>* > pool)
^
src/main.cpp:11:22: note: candidate expects 1 argument, 0 provided
src/main.cpp:10:16: note: candidate: SmartObjectPool<int>::ReturnToPool_Deleter::ReturnToPool_Deleter(const SmartObjectPool<int>::ReturnToPool_Deleter&)
struct ReturnToPool_Deleter {
^
src/main.cpp:10:16: note: candidate expects 1 argument, 0 provided
src/main.cpp:10:16: note: candidate: SmartObjectPool<int>::ReturnToPool_Deleter::ReturnToPool_Deleter(SmartObjectPool<int>::ReturnToPool_Deleter&&)
src/main.cpp:10:16: note: candidate expects 1 argument, 0 provided
src/main.cpp: In function ‘int main()’:
src/main.cpp:87:10: note: synthesized method ‘constexpr Setter::Setter()’ first required here
Setter setter;
^
Makefile:17: recipe for target 'obj/main.o' failed
make: *** [obj/main.o] Error 1
Вопрос: Как я могу установить полученный объект как член другого класса?