You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

std::vector<std::queue<Buf>>调用resize编译报错的原因及解决

问题分析与解答

问题背景

给出Buf类定义:

class  Buf  {
    const uint8_t *data;
    size_t size;
public:
    Buf() : data(nullptr), size(0) {};
    Buf(const uint8_t *data_, size_t size_) : data(data_), size(size_) { };
    Buf(Buf&& other) noexcept
        : data{std::exchange(other.data, nullptr)}, size{other.size} {};

    Buf& operator=(Buf&& other) noexcept {
        data = std::exchange(other.data, nullptr);
        size = other.size;
        return *this;
    }
    Buf(const Buf& other) = delete;
    Buf& operator=(Buf other) = delete;


    ~Buf()
    {
        free((void *)data);
    }
};

将其放入std::queue后编写主函数:

int main()
{
    std::vector<std::queue<Buf>> data;
    data.resize(10); // 编译错误
    return 0;
}

调用resize(10)时触发编译错误,核心错误信息:

error: static assertion failed: result type must be constructible from value type of input range

改用std::deque<std::queue<Buf>>则可正常编译,以下是具体分析:


一、报错原因

  1. Buf类显式删除了拷贝构造和拷贝赋值操作,仅保留默认构造、移动构造和移动赋值。
  2. std::queue<Buf>默认底层容器是std::deque<Buf>,由于Buf不可拷贝,std::deque<Buf>的拷贝构造/赋值操作被隐式删除,进而导致std::queue<Buf>的拷贝构造/赋值操作也被隐式删除。
  3. std::vector::resize在扩展容量时,部分编译器的实现会依赖元素的拷贝构造能力(例如内部内存分配算法需要拷贝已有元素或临时对象)。而std::queue<Buf>不可拷贝,因此触发静态断言错误。

二、解决办法

方法1:用emplace_back替代resize

直接在vector中构造空的std::queue<Buf>,避免依赖拷贝操作:

int main()
{
    std::vector<std::queue<Buf>> data;
    data.reserve(10); // 预分配容量,减少扩容次数
    for (int i = 0; i < 10; ++i) {
        data.emplace_back(); // 直接在vector内存中构造空队列
    }
    return 0;
}

方法2:实现Buf的拷贝构造(需注意内存安全)

如果业务允许拷贝Buf,可以实现深拷贝的拷贝构造函数,确保std::queue<Buf>具备拷贝能力:

// 在Buf类中添加拷贝构造函数
Buf(const Buf& other) {
    size = other.size;
    data = static_cast<uint8_t*>(malloc(size));
    if (data && other.data) {
        memcpy(const_cast<uint8_t*>(data), other.data, size);
    }
}
// 同时恢复拷贝赋值操作(可选,按需实现)
Buf& operator=(const Buf& other) {
    if (this != &other) {
        free(const_cast<void*>(static_cast<const void*>(data)));
        size = other.size;
        data = static_cast<uint8_t*>(malloc(size));
        if (data && other.data) {
            memcpy(const_cast<uint8_t*>(data), other.data, size);
        }
    }
    return *this;
}

三、std::deque可正常编译的原因

  1. std::deque采用分段式内存布局,扩容时不需要重新分配整块内存,也不需要移动或拷贝已有的元素。
  2. 调用std::deque::resize(10)时,它会直接在新的内存段中默认构造10个std::queue<Buf>对象,仅要求元素可默认构造(std::queue<Buf>默认构造空队列,无需构造Buf实例),完全不依赖元素的拷贝/移动能力。
  3. 因此std::deque的resize操作可以正常执行,不会触发编译错误。

内容的提问来源于stack exchange,提问作者ATK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:15:44