我想了解外部模板,但我无法让它工作。如果Foo<>
,我的目标是编译一些实例在单独的编译单元中以节省编译时间。在我的代码库中,模板参数是 enum class
,所以理论上我可以在一个编译单元中编译所有实例并将它们与项目的其余部分链接起来。
这是我想出的一个小例子:
//Foo.hpp
#pragma once
template <class T>
struct Foo {
Foo();
~Foo();
};
extern template struct Foo<int>;
//Foo.cpp
#include "Foo.hpp"
template struct Foo<int>;
//main.cpp
#include <iostream>
#include "Foo.hpp"
int main(int argc, char **argv) {
Foo<int> foo;
return 0;
}
为了进行编译,我使用了一个 makefile,归结为:
g++ -c ../Foo.cpp ../main.cpp
g++ Foo.o main.o
我用 gcc 7.1.1 得到的输出与 clang 4.0.1 基本相同是:
main.o: In function `main':
main.cpp:(.text+0x27): undefined reference to `Foo<int>::Foo()'
main.cpp:(.text+0x38): undefined reference to `Foo<int>::~Foo()'
我的主要问题是,为什么 Foo<int>::Foo()
和 Foo<int>::~Foo()
未编译成 Foo.o
?
最佳答案
因为构造函数和析构函数没有在任何地方定义,所以您只需声明它们。您在 Foo.cpp
中正确地显式实例化了模板文件,但功能仍未定义。
如果您只打算使用 Foo<int>
,那么你可以在Foo.cpp
中定义构造函数和析构函数,
template<typename T>
Foo<T>::Foo(){...} // or = default
和
template<typename T>
Foo<T>::~Foo(){...}
并且由于您在 Foo.cpp
中显式实例化了模板这一事实链接器将找到定义。否则,您需要在头文件中提供定义。
关于c++ - 了解 C++ 中的外部模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45338159/