模板运行版本与Debug不同

时间:2013-04-08 17:42:17

标签: c++ templates runtime-error

我有一个类似下面的对象

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

1 个答案:

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

  

如果模板,成员模板或类模板的成员明确专门化,那么该专业化   应该在第一次使用该特化之前声明,这将导致隐式实例化   在发生此类使用的每个翻译单位中发生; 无需诊断。 [...]

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