在我的特定设置中解析了预处理器宏之后,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版本中不存在,表现似乎不错。
有人可以解释一下这里发生了什么吗?
答案 0 :(得分:1)
这只是将实现和声明拆分为单独文件的一种方法。 .hpp
文件声明vec3
,然后#include
个.inl
文件(除非请求了非内联版本)。很容易错过#include
,因为它.hpp
的末尾,但是它就在那里。尽管声称文件是未连接的,但它们是连接的,尽管方向与预期相反。
(如果定义了GLM_EXTERNAL_TEMPLATE
,则vec3::operator=
的定义将在单独的组件中提供,而不是作为内联函数提供。)
另一个值得注意的方面是这些文件位于名为“详细信息”的目录中。这是约定,这些文件如有更改,恕不另行通知。特别是,它们可能在较旧的版本中不存在。 (它们也可能不存在于较新的版本中,但是,当您查看最新版本时,这更是一个学术问题。)
因此,总体情况是,您#include
是一个普通的头文件之一,这将确保type_vec3.hpp
和type_vec3.inl
都以此顺序#include
进行配置。这会将内联定义放在每个具有vec3
声明的翻译单元中。