我有一个类似下面的对象
template<typename T>
inline void UnusedParameter( T const& )
{
}
class Client
{
public:
template<class T>
void runFFT(T *wSamples, float const &fMult)
{
std::cout << "INSIDE RUNFFT : : :" << std::endl;
UnusedParameter(wSamples);
UnusedParameter(fMult);
}
};
在我的CPP中,我有以下内容:
#include "object.hpp"
template<>
void Client::runFFT<int16_t>(int16_t *wSamples, float const &fMult)
{
std::cout << "INSIDE INT16_T version: : :" << std::endl;
UnusedParameter(wSamples);
UnusedParameter(fMult);
}
template<>
void Client::runFFT<Ipp32f>(Ipp32f *wSamples, float const &fMult)
{
std::cout << "INSIDE IPP32F version: : :" << std::endl;
UnusedParameter(wSamples);
UnusedParameter(fMult);
}
这两个实现在我的调试代码中都没有任何问题。它进入int16_t版本没有问题,Ipp32f版本也没有问题。
但是当我尝试运行版本时它只进入模板,就像编译器只编译标题中的模板实现一样。
如何防止这种情况发生?我要删除它,只创建两种不同的方法吗?我喜欢我的模板,但这些海森堡的漏洞令人沮丧。
感谢您的任何意见。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Andy Prowl回答了这个问题,并在HPP中解决了以下问题:
template<typename T>
inline void UnusedParameter( T const& )
{
}
class Client
{
public:
template<class T>
void runFFT(T *, float const &)
{
// Thanks for Joachim for removing my Unused Parameter crap
std::cout << "INSIDE RUNFFT : : :" << std::endl;
}
};
template<>
void Client::runFFT<int16_t>(int16_t *wSamples, float const &fMult);
template<>
void Client::runFFT<Ipp32f>(Ipp32f *wSamples, float const &fMult);
现在它也可以在运行时运行。 CPP保持不变。
答案 0 :(得分:3)
问题很可能是因为您将runFFT()
和int16_t
的成员函数Ipp32f
的特化在一个单独的.cpp
文件中降级而没有提供相应的主模板之后的声明,因此实例化时的编译器(可能属于#include
仅包含Client
定义的头文件的另一个翻译单元)不知道存在那些明确的专业化。
在包含类模板定义的同一头文件中为这些特化添加声明:
template<typename T>
inline void UnusedParameter( T const& ) { }
class Client
{
public:
template<class T>
void runFFT(T *wSamples, float const &fMult)
{
std::cout << "INSIDE RUNFFT : : :" << std::endl;
UnusedParameter(wSamples);
UnusedParameter(fMult);
}
};
// DECLARE YOUR EXPLICIT SPECIALIZATIONS HERE
template<>
void Client::runFFT<int16_t>(int16_t *wSamples, float const &fMult);
template<>
void Client::runFFT<Ipp32f>(Ipp32f *wSamples, float const &fMult);
根据C ++ 11标准的第14.7.3 / 6段:
如果模板,成员模板或类模板的成员明确专门化,那么该专业化 应该在第一次使用该特化之前声明,这将导致隐式实例化 在发生此类使用的每个翻译单位中发生; 无需诊断。 [...]
“无需诊断”部分意味着如果您不遵循此规则,您的程序将会格式不正确,但您的编译器/链接器不需要告诉您。这通常会导致您观察到的那种未定义的行为。