D
Hm, okay, das habe ich mir fast schon gedacht.
Also, wenn ich eine Templateklasse habe,
z.B.
template <class T, int n, int m>
class CMatrixT
{
public: // ganz viele funktionen zum arbeiten mit (n,m)-Matrizen
private:
T m_components[n][m];
};
und eine einfache C-Struktur:
struct C4x4Matrix
{
float components[4][4];
};
dann habe ich ein Problem, bzw. plage mich ziehmlich mit reinterpret_cast's, die ziehmlich unschön sind. Die C-Struktur brauche ich für meine Schnittstelle, die template-Klasse verwende ich intern.
Es soll jetzt also die template-Klasse von der C-Strukur abgeleitet werden, quasi eine Wrapper-Klasse.
Dann könnte ich doch folgendes machen?
// generate compile time error, if bAssumedTrue
template <bool bAssumedTrue> class CCompileTimeAssertT
{ int unused[bAssumedTrue ? 1 : -1]; };
template <class T1, class T2>
void ProcCompileTimeAssertTypesRelated(T1& t1, T2& t2)
{
T1& p1 = static_cast<T1&>(t2);
T2& p2 = static_cast<T2&>(t1);
p1; p2; t1; t2;
}
template <class T1, class T2>
void ProcCompileTimeAssertTypesRelated(T1 t1[], T2 t2[])
{
T1& p1 = static_cast<T1&>(t2[0]);
T2& p2 = static_cast<T2&>(t1[0]);
p1; p2; t1; t2;
}
template <class T1, class T2>
class _validateType
{
public:
_validateType()
{
CCompileTimeAssertT<sizeof(t1.value) == sizeof(t2.value)>
_Error_Base_value_has_wrong_size; _Error_Base_value_has_wrong_size;
CCompileTimeAssertT<sizeof(T1) == sizeof(T2)>
_Error_Base_has_wrong_size; _Error_Base_has_wrong_size;
ProcCompileTimeAssertTypesRelated(t1.value, t2.value);
}
private:
T1 t1;
T2 t2;
};
// Matrizen
template <class T, int n, int m>
struct CMatrixBaseT
{ T value[n*m]; };
template <class T, int n, int m, class Base = CMatrixBaseT<T, n, m> >
class CMatrixT : public Base
{
public: // ganz viele funktionen zum arbeiten mit (n,m)-Matrizen
CMatrixT()
{ _validateType<Base, CMatrixBaseT<T, n, m> > validate; }
};
// Skalare
template <class T> struct CScalarBaseT
{ T value; };
template <class T, class Base = CScalarBaseT<T> >
class CScalarT : public Base
{
public: // ganz viele funktionen zum arbeiten mit Skalaren
CScalarT()
{ _validateType<Base, CScalarBaseT<T> > validate; }
};
extern "C" // C-Strukturen
{
struct Scalar
{ float value; };
struct Matrix4x4
{ Scalar value[4*4]; };
}
// typedefs
typedef CScalarT<float, Scalar> MeinScalar;
typedef CMatrixT<MeinScalar, 2, 8, Matrix4x4> MeineMatrix;
// Verwendung
MeinScalar x;
MeineMatrix y;
Matrix4x4* p1 = &y;
MeineMatrix* p2 = static_cast<MeineMatrix*>(p1);
Dann ist die Konvertierung in die eine Richtung schonmal implizit. Allerdings tun sich jetzt Abründe auf:
die Base muss einen member mit genau vorgegebener Größe haben und mit genau festgelegtem Typ. Das ganze wird abgesichert, würde also bereits zur Compilierzeit als Murks entarnt werden können.
Ein paar einfache Konvertierungen kann man da jetzt ja einbauen, allerdings muss ich von C4x4Matrix* nach MeineMatrix* einen static_cast verwenden.
Gibt es dafür eine elegantere Lösung?
Oder sonstige Anregungen. Die _validateType Klasse erscheint mir auch im Zwielicht, denn ihr konstruktor wird aufgerufen. (der Compiler _kann_ das optimieren, allerdings testet man Programme auch gern ohne Optimierungen.
MfG
DDR-RAM