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

C++中auto返回多类型报错,求转换crow::json::rvalue的解决方案

问题:crow::json::rvalue转换多类型时返回值推导错误

我需要将crow::json::rvalue转换为整数、布尔值或字符串,但编译时出现以下错误:

error: inconsistent deduction for auto return type: ‘int’ and then ‘bool’

报错代码:

auto convertData(const crow::json::rvalue &data) {
    std::string type = get_type_str(data.t());
    
    if(type == "Number"){
        return int(data.i());
    } else if(type == "True" || type == "False") {
        return bool(data.b());
    } 

    std::string val = data.s();
    return std::string(val);
}

编辑补充

现有实现

bsoncxx::document::value doc_value = builder
                                << "id"
                                << count
                                << "name"
                                << reqj["name"].s()
                                << "type"
                                << reqj["type"].s()
                                << "priority"
                                << priority
                                << "expense_type"
                                << reqj["expense_type"].s()
                                << "available"
                                << bool(reqj["available"].b())
                                << "life"
                                << int(reqj["life"].i())
                                << "quantity"
                                << int(reqj["quantity"].i())
                                << finalizer;
bsoncxx::document::view docview = doc_value.view();

bsoncxx::stdx::optional<mongocxx::result::insert_one> result = collection.insert_one(docview);

期望实现

bsoncxx::builder::stream::document update_builder;
            
for (auto it = reqj.begin(); it != reqj.end(); ++it) {
    if(it->key()=="id") continue;
    update_builder << "$set" << bsoncxx::builder::stream::open_document;
    update_builder << it->key() << convertData(it->value());
    update_builder << bsoncxx::builder::stream::close_document;
}

bsoncxx::document::value update = update_builder << finalizer;

bsoncxx::stdx::optional<mongocxx::result::insert_one> result = collection.insert_one(update_builder());

// The collection.insert_one updates the data in database
解决方案

C++中auto推导函数返回值时,要求所有分支返回同一种类型,你的convertData函数三个分支分别返回int、bool、std::string,类型不统一,因此触发编译错误。结合你给bsoncxx构建器传值的需求,提供两种可行方案:

方案一:直接返回bsoncxx兼容类型

返回bsoncxx::types::bson_value::view_or_value,这是bsoncxx流构建器原生支持的类型,无需额外适配:

#include <bsoncxx/types.hpp>

bsoncxx::types::bson_value::view_or_value convertData(const crow::json::rvalue &data) {
    switch(data.t()) {
        case crow::json::type::Number:
            return bsoncxx::types::b_int32{static_cast<int32_t>(data.i())};
        case crow::json::type::True:
            return bsoncxx::types::b_bool{true};
        case crow::json::type::False:
            return bsoncxx::types::b_bool{false};
        case crow::json::type::String:
            return bsoncxx::types::b_utf8{data.s()};
        default:
            // 根据需求处理Null/Array/Object等其他类型,这里示例抛出异常
            throw std::invalid_argument("Unsupported JSON type");
    }
}

修改后,update_builder << it->key() << convertData(it->value());可以直接正常工作。

方案二:用std::variant统一返回类型

如果不想直接依赖bsoncxx类型,可使用C++17的std::variant包装多类型,再通过std::visit适配到构建器:

#include <variant>

// 定义包含所有可能类型的变体
using JsonVariant = std::variant<int, bool, std::string>;

JsonVariant convertData(const crow::json::rvalue &data) {
    switch(data.t()) {
        case crow::json::type::Number:
            return static_cast<int>(data.i());
        case crow::json::type::True:
        case crow::json::type::False:
            return data.b();
        case crow::json::type::String:
            return data.s();
        default:
            throw std::invalid_argument("Unsupported JSON type");
    }
}

在循环中处理变体:

for (auto it = reqj.begin(); it != reqj.end(); ++it) {
    if(it->key()=="id") continue;
    update_builder << "$set" << bsoncxx::builder::stream::open_document;
    
    // 用std::visit处理不同类型的变体值
    std::visit([&](auto&& val) {
        update_builder << it->key() << val;
    }, convertData(it->value()));
    
    update_builder << bsoncxx::builder::stream::close_document;
}

额外修正点

原期望实现中collection.insert_one(update_builder());存在错误,因为update_builder已经通过<< finalizer生成了文档实例,应改为使用已创建的update变量:

bsoncxx::stdx::optional<mongocxx::result::insert_one> result = collection.insert_one(update.view());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:29:50