gpt4 book ai didi

c++ - 显式模板实例化如何影响链接器可以找到的内容?

转载 作者:可可西里 更新时间:2023-11-01 15:54:30 29 4
gpt4 key购买 nike

请看下面的代码,解开我的疑惑。

  1. ABC是一个模板,为什么我们把ABC类的成员函数定义放在test.cpp中却不报错?

  2. 如果我将 test.cpp 代码放入 test.h 并删除 2,那么它可以正常工作。为什么?

.

// test.h 
template <typename T>
class ABC {
public:
void foo( T& );
void bar( T& );
};
// test.cpp
template <typename T>
void ABC<T>::foo( T& ) {} // definition
template <typename T>
void ABC<T>::bar( T& ) {} // definition

template void ABC<char>::foo( char & ); // 1
template class ABC<char>; // 2
// main.cpp
#include "test.h"
int main() {
ABC<char> a;
a.foo(); // valid with 1 or 2
a.bar(); // link error if only 1, valid with 2
}

最佳答案

在这两种情况下,您都在进行显式实例化。在第二种情况下,只有 ABC<char>::foo正在被实例化,而在第一种情况下 ABC<char>::bar也正在被实例化。

另一个类似的例子可能会阐明其含义:

// test.h
template <typename T>
class ABC {
public:
void foo( T& );
void bar( T& );
};
// test.cpp
template <typename T>
void ABC<T>::foo( T& ) {} // definition
template <typename T>
void ABC<T>::bar( T& ) {} // definition

template void ABC<char>::foo( char & ); // 1
template class ABC<char>; // 2
// main.cpp
#include "test.h"
int main() {
ABC<char> a;
a.foo(); // valid with 1 or 2
a.bar(); // link error if only 1, valid with 2
}

在例子中,在main编译器看不到 foo也不bar定义,所以它不能实例化方法。编译器在处理 main.cpp 时会很高兴地接受 main 中的代码,因为你告诉它 ABC是一个模板,它具有这两个功能,并假设它们将在其他翻译单元中定义。

在包含 test.cpp 的翻译单元中,编译器会看到两个方法定义,并且可以完全处理两个实例化(方法/类)。如果只有方法实例化 ([1]) 存在,编译器将只生成该方法,并留下 bar不明确的。因此,任何包含 test.h 的代码都会链接到已编译的 test.cpp 并仅使用 foo方法将编译和链接,但使用 bar由于未定义,将无法链接。

显式实例化类模板会为所有成员方法生成符号,在这种情况下,任何包含 test.h 和针对已编译 test.cpp 目标文件的链接的翻译单元都将进行编译和链接。

关于c++ - 显式模板实例化如何影响链接器可以找到的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2735417/

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