我得到了一个典型的'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插入代码。
答案 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;
}