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

利用C++20 Concepts限制settings类方法参数类型并简化错误提示

使用C++20 Concepts限制Settings类模板参数并自定义编译错误提示

解决方案代码

#include <unordered_map>
#include <variant>
#include <concepts>
#include <type_traits>

// 定义Concept,限定仅接受long或bool类型
template<typename T>
concept SettingValueType = std::same_as<T, long> || std::same_as<T, bool>;

class Settings {
private:
    std::unordered_map<std::string, std::variant<long, bool>> data_;

public:
    // 合法类型的set方法:仅接受long或bool
    template<SettingValueType T>
    void set(const std::string& key, T value) {
        data_[key] = value;
    }

    // 合法类型的get_or_default方法:仅接受long或bool
    template<SettingValueType T>
    T get_or_default(const std::string& key, T default_val) const {
        auto it = data_.find(key);
        if (it != data_.end() && std::holds_alternative<T>(it->second)) {
            return std::get<T>(it->second);
        }
        return default_val;
    }

    // 非法类型的重载:触发自定义编译错误提示
    template<typename T>
    requires (!SettingValueType<T>)
    void set(const std::string&, T) {
        static_assert(SettingValueType<T>, "Settings::set 仅支持 long 或 bool 类型的参数");
    }

    template<typename T>
    requires (!SettingValueType<T>)
    T get_or_default(const std::string&, T) {
        static_assert(SettingValueType<T>, "Settings::get_or_default 仅支持 long 或 bool 类型的参数");
    }
};

// 测试示例
int main() {
    Settings settings;
    settings.set("user_age", 30L);
    settings.set("is_admin", true);

    long age = settings.get_or_default("user_age", 0L);
    bool is_admin = settings.get_or_default("is_admin", false);

    // 以下代码会触发编译错误,提示自定义信息
    // settings.set("username", std::string("juan"));
    // settings.get_or_default("height", 180.0f);
    return 0;
}

关键部分说明

  1. Concept 定义
    SettingValueType 概念通过std::same_as精确匹配long和bool类型,确保只有这两种类型能通过约束检查。

  2. 合法方法实现
    带SettingValueType约束的set和get_or_default方法仅处理符合要求的类型,完成正常的存储与读取逻辑,内部利用std::variant的holds_alternative和get方法保证类型安全。

  3. 自定义错误提示
    针对不符合约束的类型,我们提供了专门的重载,通过requires (!SettingValueType<T>)触发匹配,内部的static_assert直接输出清晰的错误信息,替代了编译器默认的冗长模板错误,让开发者能快速定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:21:05