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版にも問題なく入ります。

しかし、実行バージョンを試すと、コンパイラがヘッダーのテンプレート実装のみをコンパイルするように、テンプレートのみに入ります。

これを防ぐにはどうすればよいですか?これを削除して、2 つの異なるメソッドを作成しますか? テンプレートは気に入っていますが、これらのハイゼンベルクのバグはイライラさせられます。

ご意見ありがとうございます。

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

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()問題は、プライマリ テンプレートの後に対応する宣言を提供せずに、メンバー関数の特殊int16_t化をIpp32f別のファイルに追いやったという事実にある可能性が最も高い.cppため、インスタンス化の時点でコンパイラ (別の翻訳単位に属している可能性が高い) #includes の定義を含むヘッダー ファイルのみが、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:

テンプレート、メンバー テンプレート、またはクラス テンプレートのメンバーが明示的に特殊化されている場合、その特殊化は、そのような使用が発生するすべての翻訳単位で、暗黙的なインスタンス化を発生させる特殊化の最初の使用の前に宣言する必要があります。 ; 診断は必要ありません。[...]

診断は必要ありません」という部分は、このルールに従わない場合、プログラムの形式が正しくないことを意味しますが、コンパイラ/リンカーはそれを通知する必要はありません。これは通常、観察しているような未定義の動作を引き起こします。

于 2013-04-08T17:51:15.643 に答える