考虑一下,我已经像这样初步化了unique_ptr
:
unique_ptr<uint_8[]> pixels{nullptr};
之后,我决定分配一个新阵列:
pixels = new uint_8[10];
不幸的是,它不允许分配大小为10 * 8的新数组。
我知道,我可以简单地指定std::make_unique<uint_8[]>(10)
,但我只想了解智能指针。
基本上,问题是:
nullptr
转换到新数组?答案 0 :(得分:7)
pixels = new uint_8[10];
这意味着将使用operator=
std::unique_ptr
。但是,如果您查看所有operator=
overloads,您会注意到T*
没有重载std::unique_ptr<T[]>
。
您需要的方法称为reset
,并且重置存储在std::unique_ptr
中的旧值与较新的值:
pixels.reset(new uint_8[10]);
答案 1 :(得分:0)
嗯,如果我错了,请指正我,但是OP询问如何“分配”。这是一个非常具体的问题,标题也非常具体。 OP所需的方法可能不称为“重置”。
// replaces the current payload with the new empty one
pixels.reset(new uint_8[10]);
如果我对“分配”一词的含义不感到困惑,似乎上述内容并未将任何东西“分配”给pixels
。
我大胆地认为以下内容可能是查询者所喜欢的:
// array of uint8_t elements
using u8arr = std::uint8_t[];
// instance of the said array
// that contains 3 uint8 values
u8arr uar{0,1,2};
// declare unique_ptr to the same array type
std::unique_ptr<u8arr> smart_arr_;
// at last ! we assign to the "smart array"
assign(smart_arr_, uar);
// the proof of the pudding
::wprintf(L"\n\n%d\t%d\t%d", smart_arr_[0],smart_arr_[1],smart_arr_[2]);
就像是魔术一样,我已经准备好一个“赋值”实现(我之前已经准备好了):
template<typename C, size_t N>
inline auto
assign
(
std::unique_ptr<C[]> & sp_,
const C(& arr)[N]
) noexcept
-> std::unique_ptr<C[]> &
{
static_assert(std::is_trivially_copyable_v<C>);
sp_.release();
sp_ = std::make_unique<C[]>(N + 1);
void * rez_ = ::memcpy(sp_.get(), arr, N);
assert(rez_);
return sp_;
}
只是为了确保良好的旧memcpy
不会遭到反对,我使用了static_assert
来检查要复制的类型。