There is a safe way to do what you originally wanted, and that’s to add a cast-to-float-pointer converter. Doing this always finds the right memory offset for your members and avoids the problems Korval mentioned.
Basically, just add to your class:
inline operator float*() { return &x; }
inline operator const float*() const { return (const float*)&x; }
With that, you can call glVertex3fv(object) without even using the (float*) cast. Object is in this case not a pointer, but if it was, you would just dereference it.
Now you’re not dependent on where in your class the XYZ floats wind up, but you could potentially be burned if XYZ are not contiguous (which only really happens in unusual alignment schemes, say of multiple sub-structures). The safest way to prevent problems is to declare these members as a union of two or more structures, see below.
This also works for non-float types just as well. One thing to watch, though, is that you should make a habit of putting the ‘explicit’ keyword on constructors that might accidentally invoke this auto-conversion inappropriately.
I’ll give you my Vec3 template (minus the math functions) in case this helps:
template <class T> struct Vec3
{
typedef T ElemType;
static uint ElemGLID;
enum { ElemCount = 3 };
Vec3<T>() { x = y = z = 0; }
Vec3<T>(T x, T y, T z) : x(x), y(y), z(z) { }
Vec3<T>(const Vec3<T>& u) : x(u.x), y(u.y), z(u.z) { }
explicit Vec3<T>(const T val) : x(val), y(val), z(val) { }
explicit Vec3<T>(const T* xyz) : x(xyz[0]), y(xyz[1]), z(xyz[2]) { }
explicit Vec3<T>(const Vec2<T>& u) : x(u.x), y(u.y), z((T)1) { }
explicit Vec3<T>(const Vec4<T>&);
inline void Set(T _x, T _y, T _z) { x = _x; y = _y; z = _z; }
inline Vec3<T>& operator=(T val) { Set(val,val,val); return *this; }
inline Vec3<T>& operator=(const Vec3<T>& v) { Set(v.x,v.y,v.z); return *this; }
inline Vec3<T>& operator=(const Vec4<T>& v);
Bool operator==(const Vec3<T> & u) const
{
return (u.x == x && u.y == y && u.z == z) ? true : false;
}
typedef T* pointer;
operator pointer() { return &x; }
operator const pointer() const { return (const pointer)&x; }
union {
struct {
T x,y,z;
};
struct {
T s,t,u;
};
struct {
T r,g,b;
};
T elem[3]; // array access
};
};