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

含CList的结构体用于CMap编译报C2280错误的解决咨询

解决CMap存储含CList的结构体编译错误

错误原因

MFC的CList类没有默认可访问的拷贝构造函数,编译器自动为RECIPENODE生成的拷贝构造函数因包含CList被标记为删除状态,而CMap在插入、查找元素时需要调用结构体的拷贝构造函数,因此触发C2280错误。

优先保留CList的解决方法

方法1:手动实现结构体的拷贝构造与赋值运算符

给RECIPENODE添加自定义的拷贝构造函数和赋值运算符,利用CList的CopyList方法完成列表内容的深拷贝:

struct RECIPENODE {
    CString name;
    CList<CString> children;

    // 拷贝构造函数
    RECIPENODE(const RECIPENODE& other) : name(other.name) {
        children.CopyList(&other.children);
    }

    // 赋值运算符重载
    RECIPENODE& operator=(const RECIPENODE& other) {
        if (this != &other) {
            name = other.name;
            children.RemoveAll();
            children.CopyList(&other.children);
        }
        return *this;
    }
};
typedef CMap<CString, LPCTSTR, RECIPENODE, RECIPENODE> CRecipeNodeMap;
CRecipeNodeMap nodeMap;

方法2:将结构体指针存入CMap

让CMap存储RECIPENODE的指针,避免直接拷贝结构体对象。注意使用完成后要手动释放内存防止泄漏:

struct RECIPENODE {
    CString name;
    CList<CString> children;
};
typedef CMap<CString, LPCTSTR, RECIPENODE*, RECIPENODE*> CRecipeNodeMap;
CRecipeNodeMap nodeMap;

// 插入示例
RECIPENODE* pNode = new RECIPENODE;
pNode->name = _T("Test");
pNode->children.AddTail(_T("Child1"));
nodeMap.SetAt(_T("Key1"), pNode);

// 释放内存示例
POSITION pos = nodeMap.GetStartPosition();
while (pos != nullptr) {
    CString key;
    RECIPENODE* pDelNode;
    nodeMap.GetNextAssoc(pos, key, pDelNode);
    delete pDelNode;
}
nodeMap.RemoveAll();

改用std::vector的方案

如果上述方法不符合需求,将CList替换为std::vector<CString>,因为std::vector支持默认的深拷贝,编译器会自动生成合法的结构体拷贝构造函数,无需额外代码:

#include <vector>

struct RECIPENODE {
    CString name;
    std::vector<CString> children;
};
typedef CMap<CString, LPCTSTR, RECIPENODE, RECIPENODE> CRecipeNodeMap;
CRecipeNodeMap nodeMap;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:28:29