Search code examples
c++c++11c++14glm-math

Incomplete forward declaration using .inl inline files


I hope the title is not misleading.

I am making my own Linear Algebra Math library, just for practice and better understanding of math programming. I use the glm math library for reference and help. My types for now are:

class Vector2, Vector3, Vector4

all classes represent float vectors (later will be templated).

Vector2.h

#include <SomeGenericMathFunctions.h>

//Forward Declare Vector3
struct Vector3;

struct Vector2
{
public:
    float X, Y;
    //Constructors

    //Constructor in question
    Vector2(const Vector3 & inVec3);

    //Functions
    //Operators
};
#include <Vector2.inl>

Vector2.inl

//Inline Constructor definitions
.
.
.
//Constructor in question
inline Vector2::Vector2(const Vector3  & inVec3) : X(inVec3.X), Y(inVec3.Y)
{}
//Functions & operators definitions

Vector3 is later defined.This piece of code is giving me use of undefined type 'Vector3'. As far as I can understand glm is doing the same thing and everything looks fine (glm is not including vec3 anywhere inside vec2). Here is a useful link that helped me understand better what is going on and it looks like it says the same thing, separate declaration/definition etc.

I did an extended search using VS Code Maps on glm's includes and dependencies on vec2 & vec3 and I couldn't find anything. What am I missing?

EDIT: My main concern is how glm is doing what my code is trying to do. I already know the "easy/right" way but I want to understand glm' s code.

I am using c++11+


Solution

  • As far as I searched and understood glm uses forward declarations. type_vec.hpp which is included in every type_vecX.hpp file has declarations and typedefs for all vectors (float-bool,high-low precision) line 103.

    What did the trick was the use of templates. First of all I templated the structs

    template<typename T>
    struct Vector2
    {
    public:
    ...
    };
    

    and for the constructor in question the changes were

    Declaration:

    template<typename S>
    Vector2(const Vector3<S> & inVec3);
    

    Definition

    template <typename T>
    template <typename S>
    inline Vector2<T>::Vector2(const Vector3<S> & inVec3) : 
    X(static_cast<T>(inVec3.X)), 
    Y(static_cast<T>(inVec3.Y))
    {}