#c #boost #bind
#c #boost #привязка
Вопрос:
Мне нужно сопоставить a delete ptrAddr;
с a boost::function0
, но у меня возникают некоторые проблемы с выполнением этого для удаления. free работает просто отлично. Проблема, похоже, в std::ptr_fun(operator delete)
но я не могу понять, как заставить это работать без написания вспомогательного функтора.
boost::function0<void> Function;
Function = boost::bind(std::ptr_fun(free), (void*)malloc_string); //this works
Function = boost::bind(std::ptr_fun(operator delete), (void*)new_string); //doesn't work
Function(); //call function
Комментарии:
1. при работе с пользовательскими типами указатель this скрыт. также он вызывает деструктор перед удалением выделенной памяти. Не смешивайте new / delete с malloc / free
Ответ №1:
Вы можете использовать delete_ptr
из Boost.Лямбда:
boost::bind(boost::delete_ptr(), new_string);
В C 11 вы можете использовать std::default_delete<T>
:
std::bind(std::default_delete<decltype(new_string)>(), new_string);
Или просто лямбда:
[new_string]() { delete new_string; }
Комментарии:
1. должен ли я выполнять выделение через
new_ptr
, чтобы использоватьdelete_ptr
?2. @cprogrammer: Нет,
new_ptr
определено для использованияnew T(args)
, иdelete_ptr
определено для использованияdelete T
, потому что, ну, в противном случае не имеет особого смысла поступать иначе.3. есть идеи, почему я получаю bind.hpp (69): ошибка C2039: ‘result_type’: не является членом ‘boost:: lambda::delete_ptr’?
4. Я использовал boost / bind вместо boost / lambda / bind. спасибо cat
Ответ №2:
delete p;
это не вызов функции; это выражение. То, что вы хотите, не имеет смысла.
Действительно существует бесплатная функция ::operator delete()
, но она не делает того, что вы думаете.
Посмотрите на реализацию любого стандартного библиотечного контейнера (ключевое слово: распределитель) или, возможно, std::unique_ptr
, чтобы увидеть, как выполняется удаление настраиваемого объекта.
Типичная последовательность построения / уничтожения, разбитая на части, выглядит следующим образом:
void * addr = ::operator new(sizeof(T)); // allocation
T * p = ::new (addr) T; // construction
p->~T(); // destruction
::operator delete(addr); // deallocation
Первые шаги to морально эквивалентны выражению T * p = new T;
, в то время как последние соответствуют delete p;
. Однако нет другого способа вызвать конструктор, кроме как через new
выражение; и вы не должны забывать вызывать деструктор тем или иным способом.