Point3D ist KEINE Erweiterung von Point2D!
Sondern Point2D ist eine Reduzierung von Point3D. WTF? Ja ist so :P
Beweis:
struct Point2D {
double x,y;
};
struct Point3D : public Point2D {
double z;
};
static_assert(std::is_standard_layout<Point3D>::value);
main.cpp:14:1: error: static assertion failed static_assert(std::is_standard_layout<Point3D>::value);
In der C++ Sprache ist alles, was berechnet werden kann, ausdrückbar. Wird dabei das Standard Layout nicht eingehalten, ist definitiv der falsche Weg eingeschlagen worden.
Der zweite Tipp ist, dass ohne Standardlayout die Typen auch nicht POD sind. Und man kann wohl getrost annehmen, wenn ein double POD ist. Dann muss auch ein Type mit 2 oder 3 double POD sein!
Lösung:
Point2D ist auch im Point3D enthalten. Es wird halt nicht x,y,z beachtet, sondern nur x,y.
Wenn PointND als Array implementiert wird, ist das nichts anderes als array_view (string_view).
Sprich, wird der Datensatz als Point3D gespeichert (owning), sind Point2D und Point1D non-owning.
Beispiel:
template<size_t N>
struct PointNDRef : public array_view<double, N>
{
using array_view<double,N>::array_view;
};
template<size_t N>
struct PointND : public std::array<double,N>
{
operator PointNDRef<2>() {
return this->data();
}
operator PointNDRef<1>() {
return this->data();
}
};
static_assert(std::is_standard_layout<PointND>::value);
using Point3D = PointND<3>;
using Point2DRef = PointNDRef<2>;
void func(const Point2DRef p) {
p[0];
get<0>(p);
}
int main() {
Point3D p;
func(p);
return 0;
}
Die Implementation von array_view