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

C++使用类/结构体实现独立命名空间常量如何避免构造代码重复

最优实现方案

完全不需要重复编写两次构造逻辑,可按优先级选择以下方案:

方案1:直接将现有构造函数改造为constexpr(首选)

C++20起已经支持constexpr动态内存分配、constexpr异常抛出(编译期触发的异常会直接报编译错误),且glm从0.9.9.8版本开始也提供了完整的constexpr运算支持,仅需做少量改造即可:

  1. 先确认环境依赖满足要求:
    • 编译标准指定为C++20及以上
    • 升级glm到0.9.9.8及以上版本,同时定义GLM_FORCE_CONSTEXPR宏开启constexpr支持
  2. 给现有构造函数加上constexpr修饰符,内部逻辑完全不需要修改,同时建议把原代码的指针成员改为值存储,避免野指针和内存泄漏问题:
struct ColorspaceData
{
private:
    glm::vec3 sMatrix;
 
public:
    /// X red
    float xr;
    /// Y red
    float yr;
    /// Z red
    float zr;
    /// X green
    float xg;
    /// Y green
    float yg;
    /// Z green
    float zg;
    /// X blue
    float xb;
    /// y blue
    float yb;
    /// Z blue
    float zb;
    /// Whitepoint
    WhitepointData whitepoint;
    /// A [3x3] matrix used in linear-gamma transformation function
    glm::mat3 linearTransform;
    /// Result of linear-gamma transformation function as `LinearTransformData`
    TransformData linearTransformData;

    constexpr ColorspaceData(float c_xr, float c_yr, float c_xg, float c_yg, float c_xb, float c_yb,
                   StdIlluminant c_whitepoint, TransformData c_linearTransformData)
        : linearTransformData(std::move(c_linearTransformData))
    {
        xr = c_xr / c_yr;
        xg = c_xg / c_yg;
        xb = c_xb / c_yb;
        yr = 1.0f;
        yg = 1.0f;
        yb = 1.0f;
        zr = (1.0f - c_xr - c_yr) / c_yr;
        zg = (1.0f - c_xg - c_yg) / c_yg;
        zb = (1.0f - c_xb - c_yb) / c_yb;
        switch (c_whitepoint)
        {
        case (StdIlluminant::A):
            whitepoint = WhitepointData(0.44757f, 0.40745f);
            break;
        case (StdIlluminant::B):
            whitepoint = WhitepointData(0.34842f, 0.35161f);
            break;
        case (StdIlluminant::C):
            whitepoint = WhitepointData(0.31006f, 0.31616f);
            break;
        case (StdIlluminant::D50):
            whitepoint = WhitepointData(0.34567f, 0.35850f);
            break;
        case (StdIlluminant::D55):
            whitepoint = WhitepointData(0.33242f, 0.34743f);
            break;
        case (StdIlluminant::D65):
            whitepoint = WhitepointData(0.31271f, 0.32902f);
            break;
        case (StdIlluminant::D75):
            whitepoint = WhitepointData(0.29902f, 0.31485f);
            break;
        case (StdIlluminant::D93):
            whitepoint = WhitepointData(0.28315f, 0.29711f);
            break;
        case (StdIlluminant::E):
            whitepoint = WhitepointData(0.33333f, 0.33333f);
            break;
        case (StdIlluminant::F1):
            whitepoint = WhitepointData(0.31310f, 0.33727f);
            break;
        case (StdIlluminant::F2):
            whitepoint = WhitepointData(0.37208f, 0.37529f);
            break;
        case (StdIlluminant::F3):
            whitepoint = WhitepointData(0.40910f, 0.39430f);
            break;
        case (StdIlluminant::F4):
            whitepoint = WhitepointData(0.44018f, 0.40329f);
            break;
        case (StdIlluminant::F5):
            whitepoint = WhitepointData(0.31379f, 0.34531f);
            break;
        case (StdIlluminant::F6):
            whitepoint = WhitepointData(0.37790f, 0.38835f);
            break;
        case (StdIlluminant::F7):
            whitepoint = WhitepointData(0.31292f, 0.32933f);
            break;
        case (StdIlluminant::F8):
            whitepoint = WhitepointData(0.34588f, 0.35875f);
            break;
        case (StdIlluminant::F9):
            whitepoint = WhitepointData(0.37417f, 0.37281f);
            break;
        case (StdIlluminant::F10):
            whitepoint = WhitepointData(0.34609f, 0.35986f);
            break;
        case (StdIlluminant::F11):
            whitepoint = WhitepointData(0.38052f, 0.37713f);
            break;
        case (StdIlluminant::F12):
            whitepoint = WhitepointData(0.43695f, 0.40441f);
            break;
        case (StdIlluminant::LEDB1):
            whitepoint = WhitepointData(0.4560f, 0.4078f);
            break;
        case (StdIlluminant::LEDB2):
            whitepoint = WhitepointData(0.4357f, 0.4012f);
            break;
        case (StdIlluminant::LEDB3):
            whitepoint = WhitepointData(0.3756f, 0.3723f);
            break;
        case (StdIlluminant::LEDB4):
            whitepoint = WhitepointData(0.3422f, 0.3502f);
            break;
        case (StdIlluminant::LEDB5):
            whitepoint = WhitepointData(0.3118f, 0.3236f);
            break;
        case (StdIlluminant::LEDBH1):
            whitepoint = WhitepointData(0.4474f, 0.4066f);
            break;
        case (StdIlluminant::LEDRGB1):
            whitepoint = WhitepointData(0.4557f, 0.4211f);
            break;
        case (StdIlluminant::LEDV1):
            whitepoint = WhitepointData(0.4560f, 0.4548f);
            break;
        case (StdIlluminant::LEDV2):
            whitepoint = WhitepointData(0.3781f, 0.3775f);
            break;
        case (StdIlluminant::Theatre):
            whitepoint = WhitepointData(0.3141f, 0.351f);
            break;
        default:
            throw ColorException("Undefined whitepoint value");
        }
        sMatrix = glm::vec3(whitepoint.x, whitepoint.y, whitepoint.z) * glm::inverse(glm::mat3x3(xr, xg, xb, yr, yg,
                                                                                                    yb, zr, zg, zb));
        linearTransform = glm::mat3(sMatrix[0] * xr, sMatrix[1] * xg, sMatrix[2] * xb,
                                    sMatrix[0] * yr, sMatrix[1] * yg, sMatrix[2] * yb,
                                    sMatrix[0] * zr, sMatrix[1] * zg, sMatrix[2] * zb);
    }
};
  1. 直接声明编译期常量即可,完全不需要宏定义:
constexpr ColorspaceData ColorspaceDefaultSRGB{0.64f, 0.33f, 0.3f, 0.6f, 0.15f, 0.06f, StdIlluminant::D65, TransformData{1.055f, 0.0031308f, 12.0f / 5.0f, 12.92f, 0.04045f}};

方案2:抽离公共逻辑(适配C++17及更低版本)

如果暂时无法升级到C++20,可以把公共计算逻辑抽成constexpr静态函数,运行期和编译期构造函数都调用这组公共函数,不会产生代码重复:

  • 抽离三原色参数计算逻辑为constexpr静态函数
  • 抽离白点查询逻辑为constexpr静态函数
  • 两个构造函数统一调用上述函数初始化成员变量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:54:01