GLM如何在不声明内联函数并在另一个(未连接的?)文件中将其定义的函数逃脱

How does glm get away with not declaring a function inline and defining it inline in another (unconnected?) file?

本文关键字:函数 文件 逃脱 定义 连接 声明 GLM 另一个      更新时间:2023-10-16

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文件中的标题(。

这是github上的GLM: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版本中不存在这两个文件中包含的标题,这似乎表现不错。

有人可以解释一下这里发生了什么吗?

这只是将实现和声明分为单独文件的一种方式。.hpp文件声明vec3,然后 #include s .inl文件(除非请求非内部版本(。很容易错过#include,因为它在.hpp的末尾,但它在那里。尽管声称这些文件是没有连接的,但它们已连接,尽管朝着相反的方向相反。

(大概,如果定义了GLM_EXTERNAL_TEMPLATE,则vec3::operator=的定义将在单独的组件中提供,而不是作为内联函数。(

值得注意的另一个方面是这些文件在一个名为"详细信息"的目录中。这是一项惯例,说这些文件可能会更改,恕不另行通知。特别是,它们可能不存在于较旧的版本中。(它们也可能不存在于较新的版本中,但这是您查看最新版本的学术点。(

因此,总体图片是您#include是普通标头文件之一,它将确保type_vec3.hpptype_vec3.inl均为#include D。这将内联定义放在每个具有vec3声明的翻译单元中。