使用std::map存储std::pair<TermStruct,int>时编译错误的排查与解决
问题描述
试验cvc5时,为跟踪Term对象创建了如下映射:
std::map<std::string, std::pair<Term, int>> terms;
随后定义了继承自Term的子类TermStruct,实现如下:
class TermStruct : public Term { public: TermStruct(Term *t) : Term() { this->t = t; } bool isNull(); Term *getTerm() { return this->t; }; std::string toString(); private: Term *t = nullptr; };
创建了类似映射:
std::map<std::string, std::pair<TermStruct, int>> termsStructs;
尝试通过以下代码添加元素时出现编译错误:
termsStructs[str] = std::pair(term, offset);
核心错误信息:
error: no matching function for call to ‘std::pair<TermStruct, int>::pair()’
错误原因
使用std::map的operator[]时,若目标键str不存在,会先默认构造一个std::pair<TermStruct, int>对象作为该键的初始值,再执行赋值操作。但你的TermStruct类仅定义了带Term*参数的构造函数,没有无参的默认构造函数,而std::pair的默认构造要求其两个成员都能被默认构造,因此编译报错。
修复方案
方法1:给TermStruct添加默认构造函数
在TermStruct类中补充无参构造函数,确保std::pair能完成默认构造:
class TermStruct : public Term { public: // 添加默认构造函数 TermStruct() : Term(), t(nullptr) {} TermStruct(Term *t) : Term() { this->t = t; } // 其他成员函数保持不变 bool isNull(); Term *getTerm() { return this->t; }; std::string toString(); private: Term *t = nullptr; };
方法2:使用map的insert/emplace方法替代operator[]
绕过默认构造逻辑,直接构造目标元素并插入到map中:
// 用emplace直接构造并插入 termsStructs.emplace(str, std::make_pair(TermStruct(term), offset)); // 或者用insert方法 termsStructs.insert({str, std::pair<TermStruct, int>(TermStruct(term), offset)});
方法3:将pair中的TermStruct改为指针
如果业务允许,把映射类型改为存储指针,指针本身支持默认构造(默认值为nullptr):
// 修改映射类型 std::map<std::string, std::pair<TermStruct*, int>> termsStructs; // 添加元素 termsStructs[str] = std::pair(new TermStruct(term), offset); // 注意:后续需要手动释放指针内存,避免内存泄漏
内容的提问来源于stack exchange,提问作者Alberto
相关产品推荐
相关产品推荐

