gpt4 book ai didi

c++ - 在没有 'extern' 的情况下分离模板类的定义/实例化

转载 作者:行者123 更新时间:2023-11-30 04:07:10 35 4
gpt4 key购买 nike

(不再那么新)C++11 标准引入了 extern模板的关键字。它的目的是告诉编译器不应在使用时实例化模板,但它将在另一个翻译单元中实例化(因此在链接时将有可用的实例化)——至少 AFAIK。

现在,即使在 C++11 之前的时代,我们也使用类似的方法将模板类的声明/定义与其实例化分开,以加快编译速度,例如像这样:

point.h:类定义

template <int dim> struct Point {
...
void foo();
...
};

point.cpp:方法定义

#include "point.h"
template <int dim>
void Point<dim>::foo() {
...
}

point_2d.cpp:类实例化(二维版)

#include "point.cpp"
template struct Point<2>;

point_3d.cpp:类实例化(3D版)

#include "point.cpp"
template struct Point<3>;

ma​​in.cpp:2D和3D点的使用

#include "point.h"
int main(int, char**) {
Point<2> p;
p.foo();
}

现在我想知道:

  • 我们的方法是有效的 C++(03 或 11)代码还是我们只是幸运它起作用了?
  • 在 C++11 中,我们是否能够通过包含 point.cpp 来实现相同的目的?在main.cpp并声明 extern template <int dim> struct Point;

最佳答案

C++11 使用 extern告诉编译器不要实例化模板,并且语法使用的是具体类型,这与问题中建议的语法不同:

extern template struct Point<2>; 

在 C++03 中,编译器必须在观察到 Point<2> 时实例化模板。在翻译单元和 C++11 中,当与 extern 关键字结合使用时,它知道它不能。

对于你的问题,你在 C++03 中所做的是将模板的定义分离到一个单独的头文件中(带有 cpp 后缀,见下文),这种方法仍然适用于 C++ 11:

#include "point.ipp"

extern template struct Point<2>; // instantiated elsewhere

int main(int, char**) {
Point<2> p;
p.foo();
}

主观上,我也不喜欢 cpp模板头文件的后缀如此之多,以至于我想引起您的注意。这是令人困惑和误导的,尤其是当你看到一个 cpp 文件包含在另一个 cpp 文件中时。

考虑使用 ippixx作为文件扩展名加上 hpphxx分别,更清楚的是该文件包含特定模板的定义/实现。

关于c++ - 在没有 'extern' 的情况下分离模板类的定义/实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22575883/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com