Я добавляю настраиваемые распределители памяти в систему и пытаюсь сделать это правильно с помощью концепции Allocator
, но столкнулся с некоторой неопределенностью, когда достиг точки, когда тип выделенного компонента был стерт.
class Pimpl_interface {
public:
virtual ~Pimpl_interface() {}
virtual void foo() = 0;
};
template<typename T>
class Pimpl : public Pimpl_interface {
public:
void foo() override {}
};
template<typename Alloc = std::allocator<void>>
class MyType : public Alloc {
Pimpl_interface * pimpl_ = nullptr;
public:
MyType(const Alloc& alloc) : Alloc(alloc) {}
~MyType() {
if(pimpl_) {
pimpl_->~Pimpl_interface();
// What do I put here ?????
}
}
template<typename T>
void bar() {
using real_alloc_t = typename Alloc::template rebind<Pimpl<T>>::other;
real_alloc_t alloc(*static_cast<Alloc*>(this));
Pimpl<T>* ptr = alloc.allocate(1);
try {
pimpl_ = new(&ptr) Pimpl<T>();
}
catch(...) {
alloc.deallocate(ptr, 1);
throw;
}
}
};
На первый взгляд кажется, что нужно перепривязать Alloc
к Pimpl_interface
и надеяться, что это сделает правильно. Я знаю, что это будет нормально работать с std::allocator
, но предполагается ли, что это то, что пользовательские распределители должны поддерживать для всех перепривязываемых типов распределителей?
В худшем случае я могу вместо этого взять malloc/free
-подобный объект-распределитель с утиным типом, но я лучше постараюсь следовать стандартной библиотеке, если смогу.
std::shared_ptr
по существу должны хранить объект распределителя вместе с блоком управления с подсчетом ссылок, а не непосредственно вshared_ptr
... - person aschepler   schedule 17.06.2019