为什么显式模板实例化不起作用?

Why is the explicit template instantiation not working?

本文关键字:实例化 不起作用 为什么      更新时间:2023-10-16

我在头文件和代码文件中声明了一个类。

SharedResourceManager.h

#ifndef SharedResourceManager_H_
#define SharedResourceManager_H_
#include <mutex>
namespace find_object {
template <class T>
class SharedResourceManager {
public:
SharedResourceManager();
SharedResourceManager(T* resource);
~SharedResourceManager();
T* checkOutResource() const;
void checkInResource() const;
void updateResource(T* resource);
private:
T* _resource;
std::mutex lock;
};
extern template class SharedResourceManager<std::string>;
}
#endif

共享资源管理器.cpp

#include "SharedResourceManager.h"
using namespace find_object;

template <class T>
SharedResourceManager<T>::SharedResourceManager() 
{
this->_detector = NULL;
}
template <class T>
SharedResourceManager<T>::SharedResourceManager(T* resource)
{
this->_resource = resource;
}
template <class T>
SharedResourceManager<T>::~SharedResourceManager()
{
delete this->_resource;
}
template <class T>
T* SharedResourceManager<T>::checkOutResource() const
{
this->lock.lock(); //Lock the detector until released with checkInDetector
return this->_resource;
}
template <class T>
void SharedResourceManager<T>::checkInResource() const
{
this->lock.unlock();
}
template <class T>
void SharedResourceManager<T>::updateResource(T* resource) {
this->lock.lock();
delete this->_resource;
this->_resource = resource;
this->lock.unlock();
}
namespace find_object {
template class SharedResourceManager<std::string>;
}

示例.cpp

#include "SharedResourceManager.h"
#include <iostream>
using namespace std;
namespace find_object {
void func() {
std::string orig = "resource";
SharedResourceManager<std::string> srm(&orig);
std::string* resource = srm.checkOutResource();
cout << "Shared Resource Manager Created" << *resource << endl;
srm.checkInResource();
}
}
int main() {
find_object::func();
return 1;
}

我正在尝试在示例中使用此模板化类.cpp。我尝试使用我需要的类显式实例化模板,但在编译时仍然收到以下链接器错误:g++ example.cpp

/tmp/ccfssejJ.o: In function `find_object::func()':
example.cpp:(.text+0x56): undefined reference to `find_object::SharedResourceManager<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::SharedResourceManager(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)'
example.cpp:(.text+0x62): undefined reference to `find_object::SharedResourceManager<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::checkOutResource() const'
example.cpp:(.text+0xac): undefined reference to `find_object::SharedResourceManager<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::checkInResource() const'
example.cpp:(.text+0xb8): undefined reference to `find_object::SharedResourceManager<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~SharedResourceManager()'
example.cpp:(.text+0xff): undefined reference to `find_object::SharedResourceManager<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~SharedResourceManager()'
collect2: error: ld returned 1 exit status

我正在用猫建造。为什么我会收到此错误?

首先,源文件中的显式实例化必须与模板出现的命名空间相同,using 指令不会剪切它。因此,您需要将源文件修改为:

namespace find_object {
template class SharedResourceManager<Feature2D>;
}

除此之外,您可能希望在标头中使用显式模板实例化声明

template <class T>
class SharedResourceManager {
// as before
};
// Need to add this
extern template class SharedResourceManager<Feature2D>;

这将指示编译器不要隐式实例化类模板,因为实例化在其他地方。