Первоначальный вопрос (и hvd's answer) вводит служебные данные для каждого указателя, поэтому такой unique_ptr
в два раза больше, чем один, полученный с std::make_unique
. Кроме того, я бы сформулировал decltype непосредственно:
std::unique_ptr<char, decltype(&std::free)>
t_copy { strdup(t), &std::free };
Если один имеет многие из этих C-API полученных указателей, что дополнительное пространство может быть обузой задерживающего принятия безопасных C++ RAII для кода C++ оберточного существующих интерфейсов API POSIX стиля требующих быть free()
d. Другая проблема, которая может возникнуть, заключается в том, когда вы используете char const
в вышеуказанной ситуации, вы получаете ошибку компиляции, потому что вы не можете автоматически преобразовать char const *
в тип параметра free(void *)
.
Я предлагаю использовать выделенный тип удаления, не один, построенный на лету, так что пространство над головой уходит, а требуемый const_cast
также не является проблемой. Шаблон псевдоним затем может быть легко использован, чтобы обернуть C-API полученных указателей:
struct free_deleter{
template <typename T>
void operator()(T *p) const {
std::free(const_cast<std::remove_const_t<T>*>(p));
}
};
template <typename T>
using unique_C_ptr=std::unique_ptr<T,free_deleter>;
static_assert(sizeof(char *)==
sizeof(unique_C_ptr<char>),""); // ensure no overhead
Пример теперь становится
unique_C_ptr<char const> t_copy { strdup(t) };
я предположить, что этот механизм должен быть доступен в Руководстве по C++ Основного (возможно, с лучшим наименованием), поэтому он может быть доступен для баз кодов, переходящих на современный C++ (успех открыт).
Этот вопрос, наконец, объяснил мне, почему удачи полезны. – Dan