C++ 模板化函数中的共享\u ptr析构函数崩溃
在我的32位VS2015应用程序中,我有一个模板函数,可以访问库(BTK)的函数。根据此函数的类型,将调用此库函数的特定重载 这很好,但最近我在另一个(也是VS2015 32位)应用程序中使用了相同的代码和库(相同的二进制文件和代码),它在C++ 模板化函数中的共享\u ptr析构函数崩溃,c++,templates,visual-studio-2015,x86,shared-ptr,C++,Templates,Visual Studio 2015,X86,Shared Ptr,在我的32位VS2015应用程序中,我有一个模板函数,可以访问库(BTK)的函数。根据此函数的类型,将调用此库函数的特定重载 这很好,但最近我在另一个(也是VS2015 32位)应用程序中使用了相同的代码和库(相同的二进制文件和代码),它在shared\u ptr的析构函数中出现故障/访问冲突。准确地说,它在使用计数(互锁)减少时崩溃 void _Decref() { // decrement use count if (_MT_DECR(_Uses) == 0) // BOOM
shared\u ptr
的析构函数中出现故障/访问冲突。准确地说,它在使用计数(互锁)减少时崩溃
void _Decref()
{ // decrement use count
if (_MT_DECR(_Uses) == 0) // BOOM
{ // destroy managed resource, decrement weak reference count
_Destroy();
_Decwref();
}
}
现在是有趣的部分,当我用非模板版本替换模板函数时,它工作得很好
因此,如果我替换这个:
template<class T>
bool SetParameters(const std::string& group, const std::string& param, const std::vector<T>& values, const std::vector<uint8_t>& dims)
{
btk::MetaData::Pointer pParam = GetBtkMetaData(group, param);
if (!pParam)
{
pParam = AddBtkMetaData(group, param);
}
if (!pParam->HasInfo())
{
pParam->SetInfo(btk::MetaDataInfo::New(dims, values));
}
else pParam->GetInfo()->SetValues(dims, values);
return true;
}
模板
bool SetParameters(常量std::string&group、常量std::string¶m、常量std::vector&values、常量std::vector&dims)
{
btk::MetaData::Pointer pParam=GetBtkMetaData(组,参数);
if(!pParam)
{
pParam=AddBtkMetaData(组,参数);
}
如果(!pParam->HasInfo())
{
pParam->SetInfo(btk::MetaDataInfo::New(dims,值));
}
else pParam->GetInfo()->设置值(dims、值);
返回true;
}
为此:
bool C3DFile::SetParameters(const std::string& group, const std::string& param, const std::vector<int16_t>& values, const std::vector<uint8_t>& dims)
{
btk::MetaData::Pointer pParam = GetBtkMetaData(group, param);
if (!pParam)
{
pParam = AddBtkMetaData(group, param);
}
if (!pParam->HasInfo())
{
pParam->SetInfo(btk::MetaDataInfo::New(dims, values));
}
else pParam->GetInfo()->SetValues(dims, values);
return true;
}
bool C3DFile::SetParameters(常量std::string&group,常量std::string¶m,常量std::vector&values,常量std::vector&dims)
{
btk::MetaData::Pointer pParam=GetBtkMetaData(组,参数);
if(!pParam)
{
pParam=AddBtkMetaData(组,参数);
}
如果(!pParam->HasInfo())
{
pParam->SetInfo(btk::MetaDataInfo::New(dims,值));
}
else pParam->GetInfo()->设置值(dims、值);
返回true;
}
它很好用。。。显然,模板实例化对共享指针有一些影响。我有三个问题:
- 模板对此有什么影响?我可以想象代码实例化会有一些效果,但我不确定
- 为什么模板化版本可以在一个32位VS2015应用程序中使用相同的二进制文件等,而在另一个应用程序中却不能使用?(我需要使用非模板函数)
- 哪些编译器/链接器选项可能相关?我检查了编译器和链接器选项,但没有找到相关的差异
btk::MetaDataInfo::New(dims,values)
),而非模板方法只考虑可见的声明,因此可能的区别是
例如:
struct A{};
void fooT(const void*) { std::cout << "void*\n"; }
template <typename T> void barT(const T* p) { fooT(p); }
void fooT(const A*) { std::cout << "A*\n"; }
void foo(const void*) { std::cout << "void*\n"; }
void bar(const A* p) { foo(p); }
void foo(const A*) { std::cout << "A*\n"; }
int main()
{
A a{};
barT(&a); // fooT(const A*) -> A*
bar(&a); // foo(const void*) -> void*
}
struct A{};
空脚(const void*){std::coutbtk::MetaDataInfo::New
有一些重载吗?是的,很多,int,double,还有那些类型的向量。奇怪的是,它在一个应用程序中工作,但在另一个应用程序中不工作。啊,这是有意义的,但是每个应用程序的重载怎么可能不同呢?可能#include
是不同的,并且重载分辨率是如此不同耳鼻喉科。