递归型铸造

时间:2009-06-01 05:42:46

标签: c++ casting

我得到了一个典型的'vector4'类,带有一个运算符float *,可以为gl * 4fv和[]自动进行操作。 还有'const'版本用于编译器的优化以及const引用,这很好用:

typedef struct vec4
{
    ...

    // ----------------------------------------------------------------- //

        // Cast operator, for []
    inline operator float* () { 
        return (float*)this;
    }

        // Const cast operator, for const []
    inline operator const float* () const { 
        return (const float*)this;
    }

    // ----------------------------------------------------------------- //

    ...

        // Vertex / Vector 
    struct {
        float x, y, z, w;
    };  

            // Color
    struct {
        float r, g, b, a;
    };
} vec4;

我的问题是我现在使用支持的运算符vec4 *编写了一个'matrix4'类 从矩阵中提取行,并且还具有使用matrix [] []运算符的“副作用”。

typedef struct mat4
{
    ...

    // ----------------------------------------------------------------- //
            // Cast operator, for []
    inline operator vec4* () { 
        return (vec4*)this;
    }

        // Const cast operator, for const []
    inline operator const vec4* () const { 
        return (const vec4*)this;
    }
    // ----------------------------------------------------------------- //

    private:
        float f[16];
} mat4;

我的问题是,为什么编译器没有检测到转换的能力 mat4浮动*?我怀疑mat4的遗产 - > vec4 - > float *是合理的,但似乎并非如此。 我想到编译器可能会将其视为mat4 - > vec4 * - > float *,未定义, 但是这个假设是无效的,因为定义了运算符

inline operator const vec4 () const { 
    return (vec4)*this;
}

不起作用,并调用glMultMatrixf(mat4(...)); (例如)产生与没有操作符相同的错误消息。

在mat4中定义operator float *当然是不可能的,因为这将消除使用[] [](不明确的运算符)的能力

任何解决方案?或者我每次想要自动播放浮动*时都必须手动转换为vec4?自动转换是一个非常好的功能,它可以巧妙地用OpenGL插入代码。

2 个答案:

答案 0 :(得分:3)

C ++可以执行自动转换,但是标准不会执行两次连续的自动转换。

它被认为太有利于无意识的错误和含糊不清。

可能适合您的三个选项:

当您想要矩阵中的float*时,请自己明确执行第一次演员。

FuncThatWantsFloatPointer( *static_cast<Vec4*>(MyMatrix) );

在矩阵类中实现与float*的直接对话。

typedef struct mat4
{
        ...
        operator const float* () const
        { 
                return *static_cast<Vec4*>(*this);
        }

} mat4;

如果您喜欢使用方括号表示法,请在矩阵和矢量类中实施operator[]

typedef struct mat4
{
        ...
        const vec4& operator[] ( size_t index ) const
        { 
                return static_cast<Vec4*>(*this)[index];
        }

} mat4;

答案 1 :(得分:1)

......其中一条规则是不允许任何转换序列包含多个用户定义的转换(即,调用单个arguement构造函数或隐式类型转换运算符)。 - 更有效的C ++,Scott Meyers

你可能想要为vec4和mat4重载operator []。

struct vec4
{
    float& operator[](int index) { return f[index]; }
    const float& operator[](int index) const { return f[index]; }

    operator float*() { return f; }
    operator const float*() const { return f; }

    float f[4];
};

struct mat4 
{
    vec4& operator[](int row) { return v[row]; }
    const vec4& operator[](int row) const { return v[row]; }

    operator float*() { return f; }
    operator const float*() const { return f; }

    union
    {
        vec4 v[4];
        float f[16];
    };
};

int main(void)
{
    mat4 m;
    ::memset(&m, 0, sizeof(mat4));
    m[0][1] = 1;
    cout << m[0][1] << endl; // it prints 1.

    return 0;
}
相关问题