未定义对模板库成员函数的引用 class
Undefined reference to member function of template base class
考虑以下代码:
myclass.h :
template <class T>
struct S {
void f();
};
struct MyClass : public S<int>
{
void g();
};
myclass.cpp :
#include "myclass.h"
#include <iostream>
template <class T>
void S<T>::f()
{
std::cout << "f()\n";
/* some code here that could not be in header */
}
void MyClass::g()
{
std::cout << "g()\n";
}
main.cpp :
#include "myclass.h"
int main()
{
MyClass m;
m.g();
m.f(); // problem here
}
我遇到链接器错误:
undefined reference to `S::f()'
我可以在不将 S::f() 的实现转移到头文件的情况下解决这个问题吗?
为什么 S::f() 在我声明从完全专用模板库 class 派生的 MyClass 时未实例化?
如果不将 s::f() 函数的实现转移到头文件中,您将无法解决此问题。这是因为编译器在使用模板之前必须知道模板的实现。
Why S::f() not instantiated when I declare a MyClass derived from full specialized template base class?
因为您的 myclass.cpp 没有使用该模板,并且像翻译单元中所有未使用的模板一样,它们在生成的代码中毫无意义。推导一切都很好,如果 MyClass::g()
使用 S<T>::f()
你会引入该代码,生活会很美好。但是你没有,所以你必须换一种方式来拉它......
您应该能够通过显式实例化来做到这一点。请注意您的 .cpp 文件中的以下内容:
#include "myclass.h"
#include <iostream>
template <class T>
void S<T>::f()
{
std::cout << "f()\n";
}
void MyClass::g()
{
std::cout << "g()\n";
}
template struct S<int>; // ADDED
但是请注意。这仅在唯一用法为 S<int>
时才有效。额外的扩展将需要额外的显式实例化条目。
您也可以通过直接专业化来做到这一点,例如将您的 .cpp 更改为只执行此操作:
#include "MyClass.h"
#include <iostream>
template <>
void S<int>::f()
{
std::cout << "f()\n";
}
void MyClass::g()
{
std::cout << "g()\n";
}
但这在我看来是相当有限的,因为您添加的每个额外类型都需要自己的专业化。
无论如何,祝你好运。
添加显式实例化
template
struct S<int>;
到"myclass.cpp"使代码编译。
松散地说,从 S<int>
推导的只是 "instantiates" class 定义,而不是成员。
编译器此时无法实例化 f
,因为 f
的定义未知。
您需要为您使用的所有类型提供显式实例化,这在一定程度上限制了模板的实用性。
将模板定义保留在 headers 之外的一种流行方法是将它们放在自己的文件中,即 header.[=15 末尾的 #include
d =]
考虑以下代码:
myclass.h :
template <class T>
struct S {
void f();
};
struct MyClass : public S<int>
{
void g();
};
myclass.cpp :
#include "myclass.h"
#include <iostream>
template <class T>
void S<T>::f()
{
std::cout << "f()\n";
/* some code here that could not be in header */
}
void MyClass::g()
{
std::cout << "g()\n";
}
main.cpp :
#include "myclass.h"
int main()
{
MyClass m;
m.g();
m.f(); // problem here
}
我遇到链接器错误:
undefined reference to `S::f()'
我可以在不将 S::f() 的实现转移到头文件的情况下解决这个问题吗? 为什么 S::f() 在我声明从完全专用模板库 class 派生的 MyClass 时未实例化?
如果不将 s::f() 函数的实现转移到头文件中,您将无法解决此问题。这是因为编译器在使用模板之前必须知道模板的实现。
Why S::f() not instantiated when I declare a MyClass derived from full specialized template base class?
因为您的 myclass.cpp 没有使用该模板,并且像翻译单元中所有未使用的模板一样,它们在生成的代码中毫无意义。推导一切都很好,如果 MyClass::g()
使用 S<T>::f()
你会引入该代码,生活会很美好。但是你没有,所以你必须换一种方式来拉它......
您应该能够通过显式实例化来做到这一点。请注意您的 .cpp 文件中的以下内容:
#include "myclass.h"
#include <iostream>
template <class T>
void S<T>::f()
{
std::cout << "f()\n";
}
void MyClass::g()
{
std::cout << "g()\n";
}
template struct S<int>; // ADDED
但是请注意。这仅在唯一用法为 S<int>
时才有效。额外的扩展将需要额外的显式实例化条目。
您也可以通过直接专业化来做到这一点,例如将您的 .cpp 更改为只执行此操作:
#include "MyClass.h"
#include <iostream>
template <>
void S<int>::f()
{
std::cout << "f()\n";
}
void MyClass::g()
{
std::cout << "g()\n";
}
但这在我看来是相当有限的,因为您添加的每个额外类型都需要自己的专业化。
无论如何,祝你好运。
添加显式实例化
template
struct S<int>;
到"myclass.cpp"使代码编译。
松散地说,从 S<int>
推导的只是 "instantiates" class 定义,而不是成员。
编译器此时无法实例化 f
,因为 f
的定义未知。
您需要为您使用的所有类型提供显式实例化,这在一定程度上限制了模板的实用性。
将模板定义保留在 headers 之外的一种流行方法是将它们放在自己的文件中,即 header.[=15 末尾的 #include
d =]