c++ - 为什么显式模板实例化不起作用?
问题描述
我在头文件和代码文件中声明了一个类。
共享资源管理器.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;
}
我正在尝试在 example.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
我正在使用 catkin build 进行构建。为什么我会收到此错误?
解决方案
首先,源文件中的显式实例化必须与模板出现在同一个命名空间中,using 指令不会将其删除。因此,您需要将源文件修改为:
namespace find_object {
template class SharedResourceManager<Feature2D>;
}
除此之外,您可能需要在标头中明确的模板实例化声明:
template <class T>
class SharedResourceManager {
// as before
};
// Need to add this
extern template class SharedResourceManager<Feature2D>;
这指示编译器不要隐式实例化类模板,因为实例化在别处。
推荐阅读
- excel - 使用 Range 对象的 AdvancedFilter 属性的替代方法
- mysql - 我们如何使用 MySQL 单查询获得多列计数(TOP)?
- python - 为 setuptools 配置可信主机
- grep - 在许多只有部分感兴趣的文件(目标文件)中搜索缺失的字符串
- makefile - GNU Make忽略通配符指定的虚假规则?
- symfony - 仅带有 CSRF 令牌的表单
- sql - 如果您从选择中获得结果,则忽略 where 中的子句
- typescript - 获取无效的 Chai 属性:'callWith'
- php - 表名和列名的命名策略(Doctrine ORM)
- firebird - 将双精度列转换为日期时的舍入伪影