2016-05-11 43 views
1

OpenCV KalmanFilterを内部に持つクラスを作成しました。どのテンプレートパラメータもなければ、うまくコンパイルできます。OpenCV Kalman Filterとテンプレートパラメータを使用しようとしたときにコンパイルエラーが発生しました。cv :: Matt

class ClassOkay 
{ 
public: 

    struct ClassState 
    { 
     cv::KalmanFilter kalmanFilter; 
     double time; 
    }; 

    void doSomething(); 

private: 

    ClassState state; 

}; 

void ClassOkay::doSomething() 
{ 
    //Okay 
    cv::Mat& x = state.kalmanFilter.statePost; 
    x.at<double>(0) = 5; 

    //Okay 
    state.kalmanFilter.statePost.at<double>(0) = 5; 
} 

ここで、このテンプレートのタイプ名を持つオブジェクトはありませんが、テンプレートパラメータを追加すると、もはやコンパイルされません。

template<typename SubState> 
class ClassNotOkay 
{ 
public: 

    struct ClassState 
    { 
     cv::KalmanFilter kalmanFilter; 
     double time; 
    }; 

    void doSomething(); 

private: 

    ClassState state; 

}; 

template<typename SubState> 
void ClassNotOkay<SubState>::doSomething() 
{ 
    //Okay 
    cv::Mat& x = state.kalmanFilter.statePost; 
    x.at<double>(0) = 5; 

    //Not okay 
    state.kalmanFilter.statePost.at<double>(0) = 5; 
} 

私がstatePostにアクセスしようとする最後の行は、cv :: Matとして認識されないようです。次のようにコンパイラエラーがある:

../Base.h: In member function ‘void ClassNotOkay<SubState>::doSomething()’: 
../Base.h:169:37: error: expected primary-expression before ‘double’ 
    state.kalmanFilter.statePost.at<double>(0) = 5; 
            ^
../Base.h:169:37: error: expected ‘;’ before ‘double’ 

もはやatstatePostの方法であることを理解しているように私には本当に奇妙なようです。なぜ、どのようなアイデアが起こっているのですか?

+0

私は答えを知らないが、FWIW、私は、Visual Studio 2010を使用して私のマシン上でこのコードを試してみました私はあなたが描いている振る舞いを見ませんでした。 – Aenimated1

+0

@ Aenimated1 ...まあ、これは珍しいことです。ですから、もし助けがあれば、gcc 4.8.4を使ってLinuxでコンパイルしています。私の仕事の誰もが困惑しています。 –

答えて

1

OK、私は専門家ではありませんが、今起こっていることの要点を得ると思います。名前のルックアップは、テンプレートに依存する名前の可能性があるため、テンプレートのクラスと関数で複雑になる可能性があります。 (つまり、テンプレート関数またはクラスの内部で参照される名前が型またはテンプレート名であるか、または最初に解析されたときにどちらの名前でもないかどうかを判断することは不可能です)。

結果として、状況によっては名前がテンプレートまたは型名のときにコンパイラに明示的に伝えるために使用します。この例では、コンパイラはat<double>を解決する方法がわかりません。おそらく、これは、コンパイラが特定のテンプレートパラメータ(SubState)に依存する可能性があると誤って信じているためです。私はそれがバグと見なされるかどうかは分かりません。コンパイラが意図的に名前の検索を控えているかもしれません。とにかく

は、明示的にat<double>がテンプレートであることを示すことにより、コンパイラエラーを解決することができます、

state.kalmanFilter.statePost.template at<double>(0) = 5; 
+0

これは私のためにこれを対処しました。ありがとう!私は前にこのように使用されたテンプレートを見たかどうかはわかりません。この特定の使用方法は何ですか? –

+0

問題ありません!私はこれがテンプレート引数を明示的に提供しているテンプレート関数の単なる例だと思います。常に関数テンプレートの引数を明示的に指定することはできますが、コンパイラが関数のパラメータに基づいてテンプレート引数を推定することが多いため、しばしば不要です。この場合、コンパイラーがテンプレート引数を推論するためのパラメーターがないため、これが必要です。 – Aenimated1

関連する問題