为何已手动构造OrderBook仍因缺省构造函数触发编译错误?
问题描述
以下是相关代码:
Order received_order = Order(order_type, price, qty, id, curr_time); std::map<std::string, OrderBook> buy_side_symbols; auto have_symbol = buy_side_symbols.find(symbol); if (have_symbol == buy_side_symbols.end()) buy_side_symbols.emplace(symbol, OrderBook(symbol)); buy_side_symbols[symbol].addOrder(received_order);
在最后一行调用OrderBook类的addOrder()方法时,出现了“OrderBook类缺少默认构造函数”的编译错误。我认为在键不存在时已手动构造了OrderBook对象,无需默认构造函数,想请教错误原因是什么?
错误原因与解决方案
问题出在最后一行的buy_side_symbols[symbol]——std::map的operator[]有个关键特性:当访问的键不存在时,它会自动调用对应值类型的默认构造函数来创建新元素并插入到map中。
尽管你前面通过find判断并手动用emplace构造了OrderBook对象,但编译器无法在编译阶段确定symbol一定存在于map中(比如多线程场景下元素可能被其他线程删除,或者后续代码逻辑有修改的可能),因此它会强制检查OrderBook是否具备默认构造函数,以满足operator[]的潜在触发条件。
解决办法有三种:
- 复用
find返回的迭代器,避免二次查找和operator[]的使用:auto have_symbol = buy_side_symbols.find(symbol); if (have_symbol == buy_side_symbols.end()) { have_symbol = buy_side_symbols.emplace(symbol, OrderBook(symbol)).first; } have_symbol->second.addOrder(received_order); - 使用
std::map::at()方法,它仅在键存在时返回引用,不存在时抛出std::out_of_range异常,不会尝试默认构造对象:// 需确保前面的emplace逻辑已成功插入元素,否则at()会抛出异常 buy_side_symbols.at(symbol).addOrder(received_order); - 直接利用
emplace的返回值操作,简化逻辑且避免重复查找:// emplace返回pair<迭代器, bool>,bool值表示是否成功插入了新元素 auto [it, inserted] = buy_side_symbols.emplace(symbol, OrderBook(symbol)); it->second.addOrder(received_order);
内容的提问来源于stack exchange,提问作者Game Code
相关产品推荐
相关产品推荐

