Otto Nahmee
Otto Nahmee

Reputation: 143

Compilation error when trying to use OpenCV Kalman Filter and template parameters, seems to not recognize cv::Matt

I've created a class that has an OpenCV KalmanFilter inside of it (OpenCV 2.4 if anyone's wondering). Without any template parameters, it compiles just fine.

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;
}

Now when I add a template parameter, although here there are no objects with this template typename, it no longer compiles.

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;
}

The very last line where I try to access statePost, it seems to not recognize it as a cv::Mat. The compiler error is as follows:

../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’

It seems really weird to me that it no longer understands that at is a method of statePost. Any ideas why and how this is happening?

Upvotes: 1

Views: 170

Answers (1)

Aenimated1
Aenimated1

Reputation: 1624

OK, so I'm no expert, but I think I get the gist of what's happening now. Name lookup can be complex in template classes and functions because of the potential for names that are dependent on the template. (I.e., it may be impossible to determine whether a name referenced inside of a template function or class is a type or a template name or neither when it is first parsed.)

As a result, under some circumstances it is necessary to explicitly tell the compiler when a name is a template or type name. In this example, the compiler is not sure how to resolve at<double>. Presumably, this is because the compiler mistakenly believes that it could depend on the specific template parameter (SubState). I'm not sure whether that could be considered a bug - it may just be that the compiler is deliberately conservative wrt name lookup.

Anyway, you can resolve the compiler error by explicitly indicating that at<double> is a template:

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

Upvotes: 1

Related Questions