0

私は現在、私見の奇妙な問題に困惑しています。テンプレートを使用するとコンパイルが中断され、typedefを使用すると問題なく機能します。私が書いている関数は、次のシグネチャを持つ実数値の時系列から分析信号を決定することを目的としています

#ifndef USE_TEMPLATE
typedef sample_t sample_T
#else
template<typename sample_T>
#endif
analytic_err analytic(
    size_t length,
    sample_T const * const signal,
    sample_T * const amplitude,
    sample_T * const phase )
{
    typedef kissfft<sample_T> kissfft_t;
    /* ... */

kissfftKissFFT高速フーリエ変換ライブラリのC++バリアントです。さらに数行、いくつかの作業領域配列を割り当てます。

    kissfft_t::cpx_type *inout = new kissfft_t::cpx_type[padded_length];

私は意図的にstd::vectorを使用しておらず、kissfft.hhもSTLレスになるように変更しました。STLの使用または不使用については説明したくありません。このプロジェクトでは、STLは(私の決定ではなく)ノーゴーです。

そして、そこから問題が始まります。テンプレートバリアントを使用しない場合、つまり、typedef fromsample_tを定義するsample_Tと、すべてが正常に機能し、結果のプログラムはすべてのテストケースに合格します。

テンプレートの使用に切り替えるとすぐに問題が発生します。

GCCとClangの両方が、私が理解できないいくつかのエラーで救済されます。

GCCエラー

In file included from /home/dw/extradev/octuda/src/hilbert_test.cc:6:0:
signalprocess.cc: In function ‘analytic_err analytic(size_t, const sample_T*, samplT*, sample_T*)’:
signalprocess.cc:54:23: error: ‘inout’ was not declared in this scope
signalprocess.cc:54:35: error: expected type-specifier
signalprocess.cc:54:35: error: expected ‘;’
signalprocess.cc: In instantiation of ‘analytic_err analytic(size_t, const sample_T sample_T*, sample_T*) [with sample_T = float; analytic_err = analytic_err_t; size_t = long unsigned int]’:
test_analytic.cc:45:41:   required from here
signalprocess.cc:54:2: error: dependent-name ‘kissfft_t:: cpx_type’ is parsed as a n-type, but instantiation yields a type
signalprocess.cc:54:2: note: say ‘typename kissfft_t:: cpx_type’ if a type is meant
signalprocess.cc:59:2: error: dependent-name ‘kissfft_t:: cpx_type’ is parsed as a n-type, but instantiation yields a type
signalprocess.cc:59:2: note: say ‘typename kissfft_t:: cpx_type’ if a type is meant

クランエラー

In file included from ../../src/hilbert_test.cc:6:
signalprocess.cc:54:23: error: use of undeclared identifier 'inout'
        kissfft_t::cpx_type *inout = new kissfft_t::cpx_type[padded_length];
                             ^
signalprocess.cc:54:35: error: expected a type
        kissfft_t::cpx_type *inout = new kissfft_t::cpx_type[padded_length];
                                         ^
signalprocess.cc:55:6: error: use of undeclared identifier 'inout'
        if(!inout) {
            ^

and some more all following the same gist.

GCCとClangは、テンプレートを使用するときに何かが正しくないことに同意します。それで、私はここで何を間違っているのですか?

4

2 に答える 2

3

テンプレートを使用している場合、これ

kissfft_t::cpx_type *inout = new kissfft_t::cpx_type[padded_length];

これになるはずです:

typename kissfft_t::cpx_type *inout = new typename kissfft_t::cpx_type[padded_length];
^^^^^^^^note                              ^^^^^^^^note

kissfft_tテンプレート引数に依存しcpx_type依存型であるためtypename、静的値から曖昧さを解消するためにを使用する必要があります。

なぜtypename必要なのかを詳細に知るには、次のトピックを参照してください。

于 2013-01-10T15:31:28.847 に答える
1

sample_Tがテンプレートパラメータの場合、kissfft_t::cpx_typeは依存名です。テンプレートがインスタンス化されるまで、コンパイラはそれがタイプ名であると推測できないため、として記述する必要がありますtypename kissfft_t::cpx_type

テンプレートパラメータでない場合はエラーが発生するため、定義されtypenameているかどうかに関係なく、正しいことを行うには、残念ながら、より恐ろしいプリプロセッサのシェナニガンを追加する必要があります。USE_TEMPLATE

于 2013-01-10T15:34:07.697 に答える