c++ - 了解 C++ 中的外部模板

标签 c++ c++11 templates

我想了解外部模板,但我无法让它工作。如果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/

相关文章:

C++运算符>>重载问题: change object only once

C++ 变量类型条件

c++11 - std::vector of std::tuples 导致未知大小

c++ - 我可以告诉我的类是从哪个模板实例类继承的吗?

c++ - global operator 一定要写的很具体,不然链接不上

c++ - 模板队列得到错误的结果

c++ - 构建不带/clr 选项的 dll

c++ - 在 C++ 中删除文件时出错

c++ - 使用 boost::proto 构建 s-expression

java - 在 Java 中产生条件编译时错误