【问题标题】:Explicit instantiation declaration of header only template(extern template)仅标头模板的显式实例化声明(外部模板)
【发布时间】:2017-06-11 21:00:31
【问题描述】:

我正在尝试加快 GLM(OpenGL 数学)的编译时间。 GLM 大量使用 C++ 模板。

这是我迄今为止尝试过的。

math.h
#pragma once

#include <glm\glm.hpp>
extern template struct glm::tvec3<float, glm::highp>;

math.cpp
#include "math.h"
template struct glm::tvec3<float, glm::highp>;

然后我有三个使用glm::vec3 模板的文件,glm::vec3glm::tvec3&lt;float, glm::highp&gt; 的类型定义。 a,b,c 的三个文件看起来几乎一样:

a.cpp, b.cpp, c.cpp
#include "math.h"
glm::vec3 func() {
    glm::vec3 a = glm::vec3{1,1,1};
    glm::vec3 b = glm::vec3{1,1,1};
    return a + b;
}

我同时使用显式实例化定义和显式实例化声明。所以文件a,b,c 不应该导致隐式实例化。 但是编译时间和我不做一样。

【问题讨论】:

  • AFAIK,如果您将模板声明移动到单独的 .cpp 文件中并仅显式实例化所需的模板,显式实例化只能帮助加快编译时间。仅标头库并非如此。更糟糕的是:显式实例化类将生成其所有符号,包括未使用的符号
  • @AndreiR。您不必隐藏模板实现以避免隐式实例化,从而强制编译器在其他翻译单元中搜索它。这就是extern template 的全部意义 -> 强制编译器在其他翻译单元中搜索实现,而不是在当前翻译单元中实例化它。
  • @PcAF 但是这个例子应该可以工作,不是吗?
  • 我猜即使@PcAF 是正确的,这里的问题是编译器仍然必须解析整个头文件。由于在您的示例中您只使用(可能很简单)构造函数,因此编译它不会节省太多时间。
  • 这个问题引起了我的注意,我没有答案,但其他用户在尝试将外部模板与 glm 一起使用时报告了您同样的问题:cpc110.blogspot.com/2020/04/… [来自该页面:“我怀疑这是因为 #include 实际上最终确实包含了模板定义,而在这一点上,后续的 extern 模板声明只是多余的。"]

标签: c++ c++11 templates extern


【解决方案1】:

您的 math.h 仍然会导致用户包含
这就是你想要避免的事情,以加快速度。为了加快速度,创建您自己的类,其实现(在 math.cpp 中)可能使用 glm.hpp,但该类的用户不需要自己包含 glm.hpp。

这是留给学生的示例,但您需要类似:

数学.h
结构 vec3{ 双 x1,x2,x3};
vec3 plus(const vec3& a, const vec3& b);

那么当a.cpp包含math.h时,它提供了你需要的功能,但不会让你所有的编译单元都包含glm.hpp。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多