Как glm обходится без объявления встроенной функции и определения ее встроенной в другом (неподключенном?) Файле? - PullRequest
0 голосов
/ 02 июля 2019

glm имеет некоторый код, который выглядит следующим образом, после того, как макросы препроцессора разрешены на моей конкретной установке:

type_vec3.hpp

struct vec3
{
    /*...*/
    vec3& operator=(vec3 const & v);
    /*...*/
}

type_vec3.inl

inline vec3& vec3::operator=(vec3 const & v)
{ /* implementation */ }

Я не нашел ни одного связанного заголовка в файле .inl.Когда я пытаюсь переписать с таким типом компоновки, я получаю либо ошибки компоновщика (что, я считаю, связано с несоответствием между объявлением файла заголовка и определением, указанным inline), либо проблемы с пространством имен (если заголовок не включен вinl file).

Вот что такое glm на GitHub: https://github.com/g-truc/glm. Здесь находятся файлы:

https://github.com/g-truc/glm/blob/master/glm/detail/type_vec3.hpp (L179)

https://github.com/g-truc/glm/blob/master/glm/detail/type_vec3.inl (L214)

Заголовки, включенные в эти два файла, отсутствуют в используемой мной версии glm, которая, кажется, работает нормально.

Может кто-нибудь пожалуйстаобъясните, что здесь происходит?

1 Ответ

1 голос
/ 02 июля 2019

Это просто способ разделить реализацию и объявление на отдельные файлы. Файл .hpp объявляет vec3, затем #include файл .inl (если не была запрошена не встроенная версия). Легко пропустить #include, как в конце .hpp, но он есть. Несмотря на утверждение, что файлы не связаны, они связаны, хотя и в противоположном направлении, чем ожидалось.

(Предположительно, если определено GLM_EXTERNAL_TEMPLATE, определение vec3::operator= будет предоставлено в отдельном компоненте, а не в виде встроенной функции.)

Еще один аспект, который стоит отметить, заключается в том, что эти файлы находятся в каталоге, называемом «detail». Это соглашение, согласно которому эти файлы могут быть изменены без предварительного уведомления. В частности, они могут не существовать в более старых версиях. (Они также могут отсутствовать в более новых версиях, но это скорее академический вопрос, когда вы смотрите на новейшую версию.)

Таким образом, общая картина такова, что вы #include один из обычных заголовочных файлов, который гарантирует, что и type_vec3.hpp, и type_vec3.inl имеют #include d в этом порядке. Это помещает встроенное определение в каждую единицу перевода, которая имеет объявление vec3.

...