Yes... I too would shun use of inheritance in this context, as unnecessary and potentially unperformant. (Vec3 extends Vec2, I agree, no thanks!)
But phrasing your data types as c++ classes gives some syntactic sugar at no (???) performance loss. Operator overloading is broadly reviled, of course, but even its most vigorous opponents sometimes condone its use when it aligns with mathematical notation. So,
| addVec3(a, b) vs a+b
scaleVec3(x, a) vs x * a
lengthVec3(a) vs a.length()
|
and so on.
This is certainly a matter of taste. I personally prefer the latter of each, but the former is just as good. Taste is a 100% valid motivation for a design choice.
Are there issues beyond taste at play? (This is my actual & serious question, am I missing out on cycles with my approach?)
For amusement purposes only, my own are at
http://hexaflexagon.com/src/Metareal/MeLib/Source/MeMatrix.cpp
http://hexaflexagon.com/src/Metareal/MeLib/Source/MeQuat.cpp
http://hexaflexagon.com/src/Metareal/MeLib/Test/MeMatrixTests.cpp
http://hexaflexagon.com/src/Metareal/MeLib/Test/MeQuaternionsTest.cpp