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

QVector.resize()触发error2280:引用已删除函数问题排查

解决QVector/std::vector嵌套std::unique_ptr时的错误问题

先给你拆解两个问题的根源,再给出对应的解决方案:

一、QVector触发error 2280的原因与解决

你遇到的error 2280: attempting to reference a deleted function,核心原因是std::unique_ptr是独占所有权的智能指针,它的拷贝构造函数被显式删除了,而Qt 5.6.2版本的QVector在执行resize或者内存扩容时,对移动语义的支持不够完善——当它需要重新分配内存、转移元素时,会尝试调用元素的拷贝构造函数,而不是移动构造函数,这就直接触发了unique_ptr的拷贝禁用限制。

修复方案:避免触发拷贝操作,用移动/emplace方式构建容器

不要直接对空的QVector下标访问并resize,而是先通过emplace_back直接在容器内构造行,或者用std::move转移已构造好的行,这样全程不会触发拷贝:

#include <voxel.h>
int main(int argc, char *argv[]) {
    QVector<QVector<std::unique_ptr<Voxel>>> cVoxel;
    const int rows = 80, cols = 80;

    // 预分配空间,减少后续扩容的开销
    cVoxel.reserve(rows);

    for (int i = 0; i < rows; ++i) {
        // 直接在cVoxel里构造一个空的行vector
        auto& currentRow = cVoxel.emplace_back();
        currentRow.resize(cols); // 此时resize的是空vector,元素是默认构造的空unique_ptr,可安全移动

        for (int j = 0; j < cols; ++j) {
            currentRow[j].reset(new Voxel);
        }
    }
}

或者你也可以先构造好每一行,再用std::move把行转移到cVoxel中:

for (int i = 0; i < rows; ++i) {
    QVector<std::unique_ptr<Voxel>> row;
    row.resize(cols);
    for (int j = 0; j < cols; ++j) {
        row[j].reset(new Voxel);
    }
    // 用move转移所有权,不会触发拷贝
    cVoxel.push_back(std::move(row));
}

二、std::vector下标越界的原因与解决

你换成std::vector后出现的崩溃,是因为你先执行了cVoxel.resize(0),此时容器是空的,没有任何行元素,循环里直接访问cVoxel[i](i从0到79)自然会触发下标越界。

修复方案:先预分配足够的行数量

只需要把cVoxel.resize(0)改成cVoxel.resize(rows),提前创建好80个空的行vector,之后再对每一行resize即可:

#include <voxel.h>
#include <vector>
int main(int argc, char *argv[]) {
    std::vector<std::vector<std::unique_ptr<Voxel>>> cVoxel;
    const int rows = 80, cols = 80;

    // 先创建80个空的行vector
    cVoxel.resize(rows);

    for (int i = 0; i < rows; ++i) {
        auto& currentRow = cVoxel[i];
        currentRow.resize(cols);
        for (int j = 0; j < cols; ++j) {
            currentRow[j].reset(new Voxel);
        }
    }
}

当然也可以用emplace_back来逐行构造,效果是一样的。

额外小建议:试试Qt的QScopedPointer

既然你在Qt环境下,也可以考虑用Qt官方的独占智能指针QScopedPointer替代std::unique_ptr,它和Qt容器的兼容性在老版本中可能更好,用法和unique_ptr几乎一致:

#include <voxel.h>
#include <QScopedPointer>
int main(int argc, char *argv[]) {
    QVector<QVector<QScopedPointer<Voxel>>> cVoxel;
    const int rows = 80, cols = 80;

    cVoxel.resize(rows);
    for (int i = 0; i < rows; ++i) {
        auto& currentRow = cVoxel[i];
        currentRow.resize(cols);
        for (int j = 0; j < cols; ++j) {
            currentRow[j].reset(new Voxel);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:01:37