我有这个函数声明:
template<class T>
a::A& a::A::operator<<(T out) {
std::cout << out;
return (*this);
}
这个函数定义:
namespace a {
...
class A {
...
template<class T> A& operator<<(T);
我称之为:
a::A b;
b << 1;
这是 Makefile:
app: main.o A.o
g++ main.o A.o -o app
main.o: main.cpp
g++ -c main.cpp
A.o: A.cpp
g++ -c A.cpp
它给了我:
未定义符号:a::A& a::A::operator(int)
这是为什么?
一旦由 表示的类型,函数模板将在编译时变成实际的函数T
(那是,int
在你的情况下)实际上是已知的。然而,之前的情况并非如此main.cpp
已编译。当时当A.cpp
编译后,模板函数不会实例化为实际函数,因此生成的目标文件不包含该函数的二进制版本。
有两种方法可以解决这个问题。
-
将函数定义包含在头文件中。也就是说,使
template<class T>
a::A& a::A::operator<<(T out) {
std::cout << out;
return (*this);
}
头文件的一部分,并从头文件中删除函数定义.cpp
file.
这样做的效果就是any .cpp
包含此标头的文件将能够使用any模板的实例化,即对于任何值T
.
-
或者,在中包含显式模板实例化语句A.cpp
:
template a::A& a::A::operator<<(int out);
这将导致编译器在以下情况下实际实例化模板:A.cpp
被编译,并将编译后的函数包含在目标文件中。因此链接器在链接时可以找到它main.o
and A.o
在一起,一切都很好。缺点是它仅适用于特定类型(在本例中,仅适用于int
)您为其提供了显式实例化。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)