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

nlohmann json调用emplace_back()触发type_error.311异常原因咨询

nlohmann json调用emplace_back抛出type_error 311问题

报错现象

使用nlohmann json库编写代码时,遇到如下运行时报错:

terminate called after throwing an instance of 'nlohmann::detail::type_error'
  what():  [json.exception.type_error.311] cannot use emplace_back() with object
Aborted (core dumped)

查阅参考文档时发现,文档记录的311号错误描述与实际遇到的提示不符,文档标注内容为:

json.exception.type_error.311   cannot use emplace_back() with string   The emplace_back() member function can only be executed for certain JSON types. 

复现代码

初始实现代码如下,运行到标注位置时触发上述错误:

#include "common/nlohmann/json.hpp"

using json = nlohmann::json;
using ordered_json = nlohmann::ordered_json;

void AClass::do_something(){
  std::ofstream o_file(output_file);
  ordered_json json_result;
  ordered_json json_;
  json_result["output"]=json::array();

  // 获取结构体result的内容
  json_=getJsonFromResult(result);
  json_result.emplace_back(json_); //<-- 报错触发位置

  o_file<<json_result.dump();
  o_file.close();
}

ordered_json AClass::getJsonFromResult(TheResult& result){
   ordered_json json_;
   json_["blabla"]="blabla";
   return json_;
}

如果调整代码,将emplace_back()的调用移到getJsonFromResult()函数内部执行,则不会触发任何异常,修改后的代码如下:

void AClass::do_something(){
  std::ofstream o_file(output_file);
  ordered_json json_result;
  ordered_json json_;
  json_result["output"]=json::array();

  // 获取结构体result的内容
  json_=getJsonFromResult(result);
  // 移除此处的emplace_back调用

  o_file<<json_result.dump();
  o_file.close();
}

ordered_json AClass::getJsonFromResult(TheResult& result){
   ordered_json json_;
   json_["blabla"]="blabla";
   json_result["output"].emplace_back(json_); // 此处调用可正常运行(原代码此处缺右括号为输入笔误)
   return json_;
}

补充说明:json_result是AClass的成员变量。

待确认疑问:

  • 为什么emplace_back()在getJsonFromResult()函数内部调用可以正常运行,在do_something()中调用就会触发异常?
  • 该现象是否和传入参数为函数返回值有关?

问题根因

这个现象和函数返回值没有任何关系,是两个代码写法错误叠加导致的:

  • 局部变量遮蔽同名成员变量
    do_something()函数内部声明了一个和类成员变量完全同名的局部变量ordered_json json_result;,该函数内所有对json_result的操作,针对的都是这个刚创建的局部对象,而非类成员变量。
    这个局部json_result默认是JSON object类型(声明后通过[]运算符添加了"output"键,类型不会变化),而emplace_back()是JSON数组类型的专属操作方法,仅支持向数组尾部追加元素,直接对object类型调用该方法必然抛出类型错误。
  • 调用方法的目标对象错误
    代码中明确写了json_result["output"]=json::array();,说明本意是向output键对应的数组内追加元素,但实际写的是json_result.emplace_back(json_),操作目标是外层的object对象,并非内层的output数组。

移到getJsonFromResult()内可以正常运行的原因非常简单:该函数内部没有定义同名的局部json_result变量,访问的是类的成员变量,且操作目标是json_result["output"]这个数组,对数组调用emplace_back()属于合法操作,自然不会报错。
至于文档和实际报错提示不一致的问题,是因为查阅的是旧版本库的文档,本地实际使用的nlohmann json版本更高,311错误的提示覆盖了所有不支持emplace_back()的类型(包括object、string、数值等),并非只有旧文档标注的string场景。

修复方案

只需要修正do_something()中的两个问题即可:删除多余的局部变量声明避免遮蔽成员变量,同时将emplace_back()的调用目标改为output对应的数组:

void AClass::do_something(){
  std::ofstream o_file(output_file);
  ordered_json json_;
  json_result["output"]=json::array();

  json_=getJsonFromResult(result);
  json_result["output"].emplace_back(json_);

  o_file<<json_result.dump();
  o_file.close();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:24:32