Неполная прямая декларация с использованием встроенных файлов .inl - PullRequest
1 голос
/ 14 апреля 2020

Надеюсь, название не вводит в заблуждение.

Я создаю собственную библиотеку математических программ по линейной алгебре, просто для практики и лучшего понимания математического программирования. Я использую математическую библиотеку glm для справки и помощи. Мои типы на данный момент:

class Vector2, Vector3, Vector4

все классы представляют векторы с плавающей точкой (позже будет template d).

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 определяется позже. Этот фрагмент кода дает мне use of undefined type 'Vector3'. Насколько я понимаю, glm делает то же самое, и все выглядит хорошо (glm не включает vec3 где-нибудь внутри vec2). Здесь - полезная ссылка, которая помогла мне лучше понять, что происходит, и похоже, что она говорит то же самое, отдельное объявление / определение и т. Д. c.

Я провел расширенный поиск используя VS Code Maps для включений glm и зависимостей от vec2 & vec3, и я ничего не смог найти. Что мне не хватает?

РЕДАКТИРОВАТЬ: Моя главная проблема заключается в том, как glm делает то, что пытается сделать мой код. Я уже знаю «легкий / правильный» способ, но я хочу понять код glm.

Я использую c++11 +

1 Ответ

1 голос
/ 14 апреля 2020

Насколько я искал и понял glm использует предварительные объявления. type_vec.hpp, включенный в каждый файл type_vecX.hpp, имеет объявления и typedefs для всех векторов (float - bool, high - low точность) line 103.

Что за хитрость заключалась в использовании template с. Прежде всего я template d structs

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

и для рассматриваемого конструктора изменения были

Декларация:

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

Определение

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))
{}
...