我正在将一个旧的C++程序移植到现代C++中。遗留程序使用new
和delete
进行动态内存分配。我用std::unique_ptr
替换了new
,但在尝试重置unique_ptr
时出现编译错误。
这是该程序的精简版我的目标是摆脱所有裸露的new
。
#include <memory>
enum class Types {
ONE,
TWO,
};
// based on type get buffer length
int get_buffer_len(Types type) {
if(type == Types::ONE) return 10;
else if(type == Types::TWO) return 20;
else return 0;
}
int main() {
Types type = Types::ONE;
std::unique_ptr<char[]> msg{};
auto len = get_buffer_len(type);
if(len > 0) {
msg.reset(std::make_unique<char[]>(len));
}
// based on type get the actual message
if(type == Types::ONE) {
get_message(msg.get());
}
}
我得到以下编译错误:
error: no matching function for call to 'std::unique_ptr<char []>::reset(std::__detail::__unique_ptr_array_t<char []>)'
| msg.reset(std::make_unique<char[]>(len));
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如果您查看reset
函数,它需要一个ptr来存储,而不是另一个唯一的ptr:
// members of the specialization unique_ptr<T[]>
template< class U >
void reset( U ptr ) noexcept;
此功能旨在允许您reset
一个唯一的指针,同时捕获您打算使用所述unique_ptr
管理的内存。您要做的是为现有的unique_ptr
(msg
(分配一个r值unique_ptr
,c++也有一个答案:
unique_ptr& operator=( unique_ptr&& r ) noexcept;
移动赋值运算符。通过调用reset(r.release(((,然后从std::forward(r.get_deleter(((分配get_delete((,将所有权从r转移到*this。
所以你可以改为:
msg = std::make_unique<char[]>(len);