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

如何正确使用std::error_condition并解决自定义error_category编译错误

问题解决方案

错误1:no matching function for call to ‘std::error_condition::error_condition({anonymous}::condEnum&)’

原因

std::error_condition没有接收自定义枚举类类型的构造函数,你虽然定义了make_error_condition重载,但直接调用构造函数不会自动触发该重载。另外当前代码的switch语句没有加break,所有分支最终都会走到default逻辑,属于逻辑bug。

修复

将构造error_condition的代码改为调用你实现的make_error_condition,同时给switch分支补break:

std::error_condition ErrCategoryClass::default_error_condition(int err_value) const noexcept
{
    condEnum oResult;
    switch (static_cast<errEnum>(err_value))
    {
    case errEnum::ERR_NONE:
    case errEnum::ERR_A:
    case errEnum::ERR_B:
       oResult = condEnum::ERROR_CODE;
       break; // 补充break避免 fallthrough
    default:
        oResult = condEnum::UNKNOWN_ERROR;
    }
    return make_error_condition(oResult); // 改为调用自定义的make_error_condition
}

同时需要修正message函数的数组长度判断逻辑:sizeof(aErrStrings)是数组总字节数,不是元素个数,改为:

// C++17及以上可直接用std::size,低版本用sizeof(aErrStrings)/sizeof(aErrStrings[0])
if (ev < std::size(aErrStrings))

错误2+3:specialization of ‘std::is_error_condition_enum<{anonymous}::condEnum>’ after instantiation / redefinition of ‘struct std::is_error_condition_enum<{anonymous}::condEnum>’

原因

  1. 你把自定义枚举、错误类别都定义在了匿名命名空间中,匿名命名空间的类型是每个翻译单元独有、对外不可见的,你在全局std命名空间对匿名空间的类型做特化,本身就违反单一定义规则(ODR),不同翻译单元会生成重复的特化定义。
  2. 你在std中特化类型的时机太晚:代码中先用到了std::error_condition相关逻辑,已经触发了is_error_condition_enum的默认实例化,之后再做特化不符合C++标准要求。

修复

  1. 把原本放在匿名命名空间里的枚举、错误类别定义,移到自定义的具名命名空间中(比如my_err),不能再用匿名命名空间。
  2. 把std的特化代码放在自定义枚举类型定义之后、任何使用error_code/error_condition的代码之前。
    示例修改后的命名空间结构:
#include <system_error>
#include <iostream>
#include <string>

// 改用具名命名空间
namespace my_err {
    enum class condEnum
    {
        ERROR_CODE = 0,
        UNKNOWN_ERROR
    };

    enum class errEnum
    {
        ERR_NONE = 0,
        ERR_A,
        ERR_B
    };

    // ErrCategoryClass的定义、实现、make_error_code/make_error_condition的实现都放在这个命名空间里
}

// 特化要放在枚举定义之后、使用error相关接口之前
namespace std {
    template <> struct is_error_condition_enum<my_err::condEnum> : public true_type {};
    template <> struct is_error_code_enum<my_err::errEnum> : public true_type {};
}

// 后续写main等业务逻辑

整体实现评估

你自定义std::error_category的核心思路是正确的,只需要修正上述几个语法、逻辑、命名空间的细节问题,代码就能正常编译运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 04:45:06