为什么我不能分配给uint_8 []类型的unique_ptr?

时间:2018-01-04 21:45:15

标签: c++

考虑一下,我已经像这样初步化了unique_ptr

unique_ptr<uint_8[]> pixels{nullptr};

之后,我决定分配一个新阵列:

pixels = new uint_8[10];

不幸的是,它不允许分配大小为10 * 8的新数组。 我知道,我可以简单地指定std::make_unique<uint_8[]>(10),但我只想了解智能指针。

基本上,问题是:

  1. 为什么它不允许从nullptr转换到新数组?
  2. {+ 1}在C ++ 11中是某种特定类型吗?

2 个答案:

答案 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来检查要复制的类型。