1

我有一个像下面这样的对象

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版本也没有问题。

但是当我尝试运行版本时,它只输入模板,就像编译器只编译头文件中的模板实现一样。

我该如何防止这种情况发生?我应该删除它并创建两种不同的方法吗?我喜欢我的模板,但这些 Heisenberg 错误令人沮丧。

感谢您的任何意见。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

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 保持不变。

4

1 回答 1

3

问题很可能在于您将成员函数的特化降级为runFFT()一个单独的文件,而没有在主模板之后提供相应的声明,因此编译器在实例化点(可能属于另一个翻译单元s 只有包含 ) 定义的头文件不知道那些显式特化的存在。int16_tIpp32f.cpp#includeClient

将这些特化的声明放在包含类模板定义的同一头文件中:

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 段:

如果模板、成员模板或类模板的成员被显式特化,则应在第一次使用该特化之前声明该特化,这将导致发生隐式实例化,在每个翻译单元中出现这种使用; 不需要诊断。[...]

不需要诊断”部分意味着如果您不遵循此规则,您的程序将是格式错误的,但您的编译器/链接器不需要告诉您。这通常会导致您正在观察的那种未定义的行为。

于 2013-04-08T17:51:15.643 回答