使用 class/struct 和大构造函数在单独的命名空间中保持常量

Constant in separate namespace using class/struct with a big constuctor

我有一个结构:

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;
    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)
    {
        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 = new WhitepointData(0.44757f, 0.40745f);
            break;
        case (StdIlluminant::B):
            whitepoint = new WhitepointData(0.34842f, 0.35161f);
            break;
        case (StdIlluminant::C):
            whitepoint = new WhitepointData(0.31006f, 0.31616f);
            break;
        case (StdIlluminant::D50):
            whitepoint = new WhitepointData(0.34567f, 0.35850f);
            break;
        case (StdIlluminant::D55):
            whitepoint = new WhitepointData(0.33242f, 0.34743f);
            break;
        case (StdIlluminant::D65):
            whitepoint = new WhitepointData(0.31271f, 0.32902f);
            break;
        case (StdIlluminant::D75):
            whitepoint = new WhitepointData(0.29902f, 0.31485f);
            break;
        case (StdIlluminant::D93):
            whitepoint = new WhitepointData(0.28315f, 0.29711f);
            break;
        case (StdIlluminant::E):
            whitepoint = new WhitepointData(0.33333f, 0.33333f);
            break;
        case (StdIlluminant::F1):
            whitepoint = new WhitepointData(0.31310f, 0.33727f);
            break;
        case (StdIlluminant::F2):
            whitepoint = new WhitepointData(0.37208f, 0.37529f);
            break;
        case (StdIlluminant::F3):
            whitepoint = new WhitepointData(0.40910f, 0.39430f);
            break;
        case (StdIlluminant::F4):
            whitepoint = new WhitepointData(0.44018f, 0.40329f);
            break;
        case (StdIlluminant::F5):
            whitepoint = new WhitepointData(0.31379f, 0.34531f);
            break;
        case (StdIlluminant::F6):
            whitepoint = new WhitepointData(0.37790f, 0.38835f);
            break;
        case (StdIlluminant::F7):
            whitepoint = new WhitepointData(0.31292f, 0.32933f);
            break;
        case (StdIlluminant::F8):
            whitepoint = new WhitepointData(0.34588f, 0.35875f);
            break;
        case (StdIlluminant::F9):
            whitepoint = new WhitepointData(0.37417f, 0.37281f);
            break;
        case (StdIlluminant::F10):
            whitepoint = new WhitepointData(0.34609f, 0.35986f);
            break;
        case (StdIlluminant::F11):
            whitepoint = new WhitepointData(0.38052f, 0.37713f);
            break;
        case (StdIlluminant::F12):
            whitepoint = new WhitepointData(0.43695f, 0.40441f);
            break;
        case (StdIlluminant::LEDB1):
            whitepoint = new WhitepointData(0.4560f, 0.4078f);
            break;
        case (StdIlluminant::LEDB2):
            whitepoint = new WhitepointData(0.4357f, 0.4012f);
            break;
        case (StdIlluminant::LEDB3):
            whitepoint = new WhitepointData(0.3756f, 0.3723f);
            break;
        case (StdIlluminant::LEDB4):
            whitepoint = new WhitepointData(0.3422f, 0.3502f);
            break;
        case (StdIlluminant::LEDB5):
            whitepoint = new WhitepointData(0.3118f, 0.3236f);
            break;
        case (StdIlluminant::LEDBH1):
            whitepoint = new WhitepointData(0.4474f, 0.4066f);
            break;
        case (StdIlluminant::LEDRGB1):
            whitepoint = new WhitepointData(0.4557f, 0.4211f);
            break;
        case (StdIlluminant::LEDV1):
            whitepoint = new WhitepointData(0.4560f, 0.4548f);
            break;
        case (StdIlluminant::LEDV2):
            whitepoint = new WhitepointData(0.3781f, 0.3775f);
            break;
        case (StdIlluminant::Theatre):
            whitepoint = new WhitepointData(0.3141f, 0.351f);
            break;
        default:
            throw new 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);
        linearTransformData = &c_linearTransformData;
    }
};

我需要声明 CT 变量。它适用于#define:

#define ColorspaceDefaultSRGB ColorspaceData(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))

但是描述 constexpr 构造函数有太多这样的重复代码(我在之前的 中有解释):

constexpr ColorspaceData(float p_xr, float p_yr): xr(p_xr), yr(p_yr) ... (other constructor code) {};

需要将所有行描述两次?为构造函数声明一个函数?最好的方法是什么?

如果您不能使整个构造函数 constexpr 包含应复制的所有代码,我建议使用 constexpr init 方法。请注意,如果函数是 constexpr,即使在这种情况下非 constexpr 也可以调用它。

 constexpr void init(...){
    //a lot of stuff
 }
 ColorspaceData(...){
     init(...)
     //not constexpr stuff
 }
 constexpr ColorspaceData(...){
     init(...)
     //constexpr stuff
 }