如果不声明内联函数并在另一个(未连接?)文件中内联定义它,glm如何摆脱?

时间:2019-07-02 02:39:40

标签: c++ glm

在我的特定设置中解析了预处理器宏之后,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版本中不存在,表现似乎不错。

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

1 个答案:

答案 0 :(得分:1)

这只是将实现和声明拆分为单独文件的一种方法。 .hpp文件声明vec3,然后#include.inl文件(除非请求了非内联版本)。很容易错过#include,因为它.hpp的末尾,但是它就在那里。尽管声称文件是未连接的,但它们是连接的,尽管方向与预期相反。

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

另一个值得注意的方面是这些文件位于名为“详细信息”的目录中。这是约定,这些文件如有更改,恕不另行通知。特别是,它们可能在较旧的版本中不存在。 (它们也可能不存在于较新的版本中,但是,当您查看最新版本时,这更是一个学术问题。)

因此,总体情况是,您#include是一个普通的头文件之一,这将确保type_vec3.hpptype_vec3.inl都以此顺序#include进行配置。这会将内联定义放在每个具有vec3声明的翻译单元中。