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

C++代码优化求助:宏粘贴错误及JSON类型检查代码简化

Solution for Redundant JSON Type Checking in C++

Hey there, let's fix that repetitive JSON type checking code and resolve the macro preprocessing error you're hitting. Here's how to approach this:

Why Your Macro Failed

The error "pasting "<" and "string" does not give a valid preprocessing token" happens because the C++ preprocessor treats < as a separate operator token, and string as an identifier. Trying to splice them together with ## doesn't work—preprocessor tokens can't be formed by combining these distinct elements that way.

Better Option: Use a Template Function (Type-Safe & Clean)

Instead of relying on macros (which are error-prone and lack type safety), a template function is the idiomatic C++ way to eliminate repetitive code. Here's how to implement it:

#include <nlohmann/json.hpp> // Adjust based on your JSON library
using json = nlohmann::json;

// Assume YourResultType is the type of your _result variable
template<typename T>
bool validate_json_field(const json& incoming_json, const std::string& field_name, YourResultType& result) {
    if (incoming_json.contains(field_name) && incoming_json[field_name].is<T>()) {
        __TRACE("argument type OK\n");
        return true;
    } else {
        __ERROR("invalid type for field: " << field_name << "\n");
        result.rc = ERROR_CODE_INVALID_TYPE;
        // Add your _req_ error handling logic here (e.g., setting error messages)
        return false;
    }
}

How to Use It

Now you can replace all those duplicate code blocks with a single function call for each field type:

// Check for a string field
if (!validate_json_field<std::string>(json_data_incomming, "value", _result)) {
    // Exit early or handle error
    return;
}

// Check for an integer field
if (!validate_json_field<int>(json_data_incomming, "count", _result)) {
    return;
}

// Works with any type your JSON library supports (e.g., bool, double)
if (!validate_json_field<bool>(json_data_incomming, "is_active", _result)) {
    return;
}

This approach is:

  • Type-safe: The compiler will catch invalid type arguments at compile time.
  • Maintainable: If you need to adjust the error logic, you only change it once in the template function.
  • Readable: The function name makes it clear what's happening, unlike opaque macros.

If you have a specific reason to stick with macros, you can avoid the token-pasting issue by passing the full type as a parameter instead of trying to splice it. Here's a working macro:

#define CHECK_JSON_FIELD(json_obj, field, type, result) \
    do { \
        if ((json_obj).contains(field) && (json_obj)[field].is<type>()) { \
            __TRACE("argument type OK\n"); \
        } else { \
            __ERROR("invalid type for field: " field "\n"); \
            (result).rc = ERROR_CODE_INVALID_TYPE; \
            // Add your _req_ error handling here \
        } \
    } while(0)

Usage Example

CHECK_JSON_FIELD(json_data_incomming, "value", std::string, _result);
CHECK_JSON_FIELD(json_data_incomming, "age", int, _result);

The do { ... } while(0) wrapper ensures the macro behaves like a single statement, preventing issues with if/else blocks without braces.


内容的提问来源于stack exchange,提问作者Martin Borůšek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:11:14