【问题标题】:assigning an unique_ptr with std::move not working用 std::move 分配一个 unique_ptr 不起作用
【发布时间】:2020-08-23 06:24:14
【问题描述】:

我对 c++ 和智能指针很陌生,但我的理解是我可以用 std::move(another unique_ptr) 分配一个 unique_ptr。 当我尝试使用 std::move(..) 分配 unique_ptr 时,它会引发以下错误:

二进制“=”:未找到采用“std::unique_ptr>”类型的右侧操作数的运算符

下面的代码块是引发错误的地方,在倒数第二行。

template<typename T>
void wave::WaveReader::readSamples(std::istream& input, int nr_of_bytes)
{
    std::unique_ptr<T[]> a = std::make_unique<T[]>(this->data_chunk.subChunk2Size);
    input.read(reinterpret_cast<char*>(this->data.data.get()), this->data_chunk.subChunk2Size);
    this->data.length = (this->fmt.bitsPerSample / (nr_of_bytes * 8));
    this->data.width = this->data_chunk.subChunk2Size / (this->fmt.bitsPerSample / 8);
    this->data.data = std::move(a);
    std::cout << sizeof(T) << std::endl;
}

一些额外的代码:

class WaveReader
{
private:
    RIFFCHUNK riff;
    FMTCHUNK fmt;
    DATACHUNK data_chunk;
    Array<int8_t> data;
    std::variant<Array<int8_t>,Array<uint16_t>,Array<uint32_t>> samples;
public:
    void read(std::string filepath);
private:
    void readSamples(std::istream& input);
    template<typename T>
    void readSamples(std::istream& input,int nr_of_bytes);
    std::string getDataChunkID(DATACHUNK& data);
    void read_RIFFCHUNK(std::istream& input, RIFFCHUNK& riff);
    void read_FMTCHUNK(std::istream& input, FMTCHUNK& fmt);
    void read_DATACHUNK(std::istream& input, DATACHUNK& data, FMTCHUNK& fmt);
};

我尝试分配的具有 unique_ptr 的数组类

template <typename T>
struct Array
{
    std::unique_ptr<T[]> data;
    uint32_t length;
    uint32_t width;
    Array(int width, int length) : width(width), length(length)
    {
        data = std::make_unique<T[]>(width);
    }
    Array() : width(0), length(0)
    {
        data = std::make_unique<T[]>(0);
    }
    T operator[](const Position& pos) { return data[(pos.x * length) + pos.y]; }
};

额外代码: 此代码读取文件

void wave::WaveReader::read(std::string filename)
{
    std::ifstream file(filename, std::ios::binary);
    //read riff chunk
    read_RIFFCHUNK(file, this->riff);
    //read fmt chunk
    read_FMTCHUNK(file, this->fmt);
    //read data chunk, fills data object
    read_DATACHUNK(file, this->data_chunk, fmt);
    this->readSamples(file);
}

我使用此代码来确定样本存储的类型

void wave::WaveReader::readSamples(std::istream& input)
{
    //get Type
    switch (fmt.bitsPerSample)
    {
    case 8:
        readSamples<uint8_t>(input,1);
        break;
    case 16:
        readSamples<int16_t>(input, 2);
        break;
    case 24:
        readSamples<int32_t>(input, 3);
        break;
    case 32:
        readSamples<int32_t>(input, 4);
        break;
    default:
        abort(); // need to change this probably
    }
}

当我将数组结构中的 std::unique_ptr 更改为正常的 int 时,它确实可以正常工作。当我将其更改为 T 时,它不起作用。

【问题讨论】:

  • 那么,readSamples 中的 T 是什么?我的猜测是您的代码中不是int8_t。例如,unique_ptr&lt;int8_t&gt;unique_ptr&lt;int16_t&gt; 不兼容。

标签: c++ smart-pointers unique-ptr


【解决方案1】:

当您执行x = std::move(y) 并且ystd::unique_ptr&lt;T&gt; 类型时,那么x 也必须是std::unique_ptr&lt;T&gt; 类型(或两个指针可隐式转换的类型),否则赋值将不起作用。如图所示,您的代码只有在 Tint8_t 时才能工作,因为这是左边的内容。

【讨论】:

  • 哦,好吧,现在我明白了,我实际上是说样本而不是数据,完全忘了删除它。感谢您解决问题。
  • "那么 x 也必须是 std::unique_ptr&lt;T&gt;" 类型 - 或者 std::unique_ptr&lt;Y&gt; 如果 T* 可以隐式转换为 Y*,例如如果 @ 987654333@ 是T 的基类。但这不适用于数组和整数等基本类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-07
  • 2014-02-27
  • 2019-07-09
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
相关资源
最近更新 更多