从std :: vector获取指向数组的唯一指针

时间:2014-03-01 00:59:32

标签: arrays pointers c++11 vector

我正在尝试使用两个对集合有不同想法的库。我从一个返回const向量&:

的数据中获取数据
const std::vector<uint8_t>& Lib1::getData();

另一个采用与ctor参数相同的数据,但形式略有不同,并且在将数据传递给基类之前需要拥有数据:

class Lib2 : public Lib2Base
{
private:
    std::unique_ptr<uint8_t []> buffer;
public:
    Lib2(std::unique_ptr<uint8_t []> & p_buffer; size_t p_length) :
        buffer(move(p_buffer)), Lib2Base(p_buffer.get(), p_length)
    {}  
}

我需要一个指向Lib2的共享指针,该Lib2由Lib1中的数据构成。我知道在封面下,矢量是连续的,就像数组一样,所以我试图用vector::data()处理转换,如下所示:

vector<uint8_t> buffer(lib1->getData());
auto bufferPtr = make_unique<uint8_t *>(buffer.data());
shared_ptr<Lib2> output = make_shared<Lib2>(&bufferPtr, buffer.size());

此时,我希望bufferPtr是指向数组开头的指针的唯一指针。但是最后一行导致错误:

C2664: 'Lib2(const Lib2 &)' cannot convert argument 1 
from 'std::unique_ptr<uint8_t *, std::default_delete<_Ty>>' 
to   'std::unique_ptr<uint8_t [], std::default_delete<_Ty>> &'

(为了便于阅读,添加了对齐)。我觉得我可能会有一个额外的间接水平在这里,但看了这么久,我看不到在哪里。

1 个答案:

答案 0 :(得分:1)

make_unique<uint8_t *>是指向 uint8_t的指针,其具有与动态数组uint8_tdelete不同的删除器} vs delete[]

要使该错误消失,您只需将make_unique<uint8_t *>替换为make_unique<uint8_t[]>即可。不幸的是,这仅仅解决了编译器错误。还有一个概念上的错误。

即,“它取得了数据的所有权”。向量已经拥有的数据。您正试图分享所有权,并告诉他们两者都是唯一的所有者。当第一个被破坏时,另一个将崩溃,因为这是未定义的行为。如果Lib2确实需要unique_ptr<uint8_t[]>非常奇怪,除了C兼容性之外,unique_ptr<T[]>确实没有理由存在...),那么你的唯一的选择是在内存中实际分配一个新的T[],将数据从向量复制到该内存,并将unique_ptr指向该内存Lib2。抱歉。

template<class T>
std::unique_ptr<T[]> make_unique_array_from_vec(const std::vector<T>& vec) {
    std::unique_ptr<T[]> ptr(new T[vec.size()]);
    std::copy(vec.begin(), vec.end(), ptr.get());
    return ptr;
}