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

nlohmann/json隐式转换疑问:编译通过与运行时崩溃解析

关于nlohmann/json库隐式转换的两个问题

问题一:为何编译器允许X x("{}"_json);?

给出的代码示例:

#include <nlohmann/json.hpp>

using nlohmann::json;
struct X {
    X(const std::string& s){}
};
int main() {
    X x("{}"_json); // 为何编译器允许此操作?
}

原因解析

这既不是bug也不是意外副作用,是C++隐式转换规则和nlohmann/json库设计共同作用的结果:

  • "{}"_json会构造一个**json对象类型(而非字符串类型)**的实例。
  • nlohmann/json的json类提供了operator std::string() const隐式转换运算符,用于将json值转换为std::string——但这个转换仅在json值本身是字符串类型时才合法,否则会在运行时抛出异常。
  • 编译阶段,编译器只会检查是否存在可行的转换路径:json对象可以隐式转换为std::string,而X的构造函数接受const std::string&,因此转换链(json → std::string → X)合法,编译器允许通过。
  • 注意:如果代码实际触发这个转换(比如构造函数中使用了s参数),运行时同样会抛出类型错误异常,示例中X的构造函数是空实现,可能被编译器优化掉了转换操作,所以没表现出异常。

问题二:为何std::string j = "{}"_json;运行时失败?

给出的代码示例:

#include <nlohmann/json.hpp>
using nlohmann::json;
int main() {
  std::string j = "{}"_json;  
}

报错信息(翻译后)

程序终止,抛出了nlohmann::json_abi_v3_11_2::detail::type_error异常实例
异常信息:[json.exception.type_error.302] 类型必须为字符串,但当前是对象类型

原因解析

  • "{}"_json构造的是一个json对象(object类型),而非json字符串(string类型)。
  • 当直接将这个json对象赋值给std::string时,会触发json类的operator std::string()转换运算符,该运算符会检查当前json值的类型:只有值是字符串类型时才会返回对应字符串,否则抛出type_error异常。
  • 这个行为是库的设计意图:隐式转换仅在类型匹配时合法,避免静默类型错误,因此运行时会抛出明确的异常提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 19:35:25