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
-specified 定义不匹配)或命名空间问题(如果头文件不包含在 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
文件.inl
(除非请求了非内联版本)。很容易错过#include
结尾处的.hpp
,但它就在那里。尽管声称文件未连接,但它们是连接的,尽管方向与预期相反。
(大概,如果GLM_EXTERNAL_TEMPLATE
定义了,定义vec3::operator=
将在单独的组件中提供,而不是作为内联函数。)
另一个值得注意的方面是这些文件位于一个名为“detail”的目录中。这是一个约定,表示这些文件如有更改,恕不另行通知。特别是,它们可能不存在于旧版本中。(它们也可能不存在于较新的版本中,但当您查看最新版本时,这更像是一个学术点。)
因此,总体情况是您#include
是正常的头文件之一,它将确保两者type_vec3.hpp
都type_vec3.inl
按#include
顺序排列。这将内联定义放在具有vec3
声明的每个翻译单元中。