如果模板类构造函数和成员函数的定义与使用分离,则G++链接器找不到它们
G++ linker does not find template class constructor and member function if their definition is separated from their use
可能重复:
为什么模板只能在头文件中实现?
在开发一个具有某种类型意识的小解析器时,我遇到了以下难题。简而言之:
GNU g++"忘记"模板成员函数定义,除非它是在使用它的同一文件中定义的
有什么想法吗?
案件档案
为了隔离这个问题,我将代码分解为三个文件:
头文件Temple.hpp:
#ifndef _TEMPLE
#define _TEMPLE
template <class T> class Temple {
private:
T deity;
public:
Temple ( T value );
T see ();
};
#endif
然后是相应的C++实现文件Temple.cpp:
#include "Temple.hpp"
template <class T> Temple<T>::Temple ( T value ) : deity( value ) {}
template <class T> T Temple<T>::see () { return deity; }
最后是一个主应用程序调用文件templetst.cpp:中的内容
#include "Temple.hpp"
int main () {
bool b(false);
Temple<bool> t( b );
t.see();
}
应该发生的是,构造一个局部变量Temple<bool> t
,然后提供由模板定义的(模板扩展的(方法bool see()
。
编译失败☹
然而,当我尝试使用编译C++源代码时
g++ *.cpp
(或者显式地命名文件(,我在gcc版本4.2.1上得到了一个链接器错误:
/tmp//ccWAFJDF.o(.text+0x24): In function `main':
: undefined reference to `Temple<bool>::Temple(bool)'
/tmp//ccWAFJDF.o(.text+0x2f): In function `main':
: undefined reference to `Temple<bool>::see()'
collect2: ld returned 1 exit status
并且在gcc 4.0.1上稍微不那么冗长:
/usr/bin/ld: Undefined symbols:
Temple<bool>::see()
Temple<bool>::Temple(bool)
collect2: ld returned 1 exit status
无论如何,从这里我得出结论,templetest.cpp既不能访问构造函数,也不能访问具体模板类的成员函数。
编译工作☻
到目前为止还很糟糕,但还有另一种编译方法,即将所有代码放入一个源文件中,然后进行编译。令人惊讶的是,进展顺利。您可以简单地使用stdin流式传输尝试这种方法:
cat *.cpp | g++ -x c++ -
如果将文件Temple.cpp手动合并到Temple.hpp中以产生,则会获得同样的成功
template <class T> class Temple {
private:
T deity;
public:
Temple ( T value );
T see ();
};
template <class T> Temple<T>::Temple ( T value ) : deity( value ) {}
template <class T> T Temple<T>::see () { return deity; }
然后使用进行编译
g++ templetest.cpp
GNU CC似乎只能记住Temple.cpp中的成员函数定义属于模板类,如果它们在同一文件中的话。
在main.c中,在声明Temple<bool>
类型的变量时,实例化该类型。为了实例化模板化类型,您必须能够访问该类型的所有实现。
你有两个选择。
第一个也是传统的选择是将整个实现放在头文件中,并删除Temple.cpp文件:
// UNTESTED
template <class T> class Temple {
private:
T deity;
public:
Temple ( T value ) : deity(value) {}
T see () { return deity; }
};
这样,模板的任何用户都可以用他们选择的任何类型来实例化它。
第二种也是不太传统的方法是在唯一可以访问整个实现的位置显式实例化Temple<bool>
,即temple.cpp:
// temple.cpp
...
// At the very end of the file:
template class Temple<bool>;
但是,请注意,模板类Temple
的用户只能使用您创建的实例。在这种情况下,他们只能使用bool
。
- C++:如何读取分离变量,然后读取向量
- 分离一个静态常量 std::thread?
- .h 和.cpp文件分离时出错,但仅使用 .h 文件时没有错误.我做错了什么?
- 如何在 c++ 中将数据与文件流分离
- 为什么堆栈和堆在内存中分离得如此之多?
- 具有可分离内核的 2D 模糊卷积
- 为什么即使调用了析构函数,C++11 中的分离线程也可以执行
- 防止编译器分离函数的指令
- 分离库的主机端和 CUDA 设备端版本
- C++将文件行分离为String和Int
- 分离类所有权和使用,生成最佳(快速)代码
- 动态空间分离C++程序中的输入
- 如何从几乎排序的链表中分离放错位置的元素?
- 检查分离的线程是否还活着?
- 真的需要在 .h 和 .cpp 文件中分离 c++ 结构吗?
- 为什么分离线程没有得到输出消息
- 将偶数和奇数随机数分离并打印出来
- 如何"stop"正在等待条件变量的分离线程?
- 有没有办法在一段时间后将流程从流出中分离出来
- 如何在模板参数中分离函数类型返回类型和参数