IsaacS
IsaacS

Reputation: 3621

"undefined reference to" error. (from a member function to static member variable)

I got a following error upon linking.

A member variable ClassBB::THR can't be accessed from a function ClassBB::bound().

What's strange is, from ClassBB::setThreshold(T v) function, which seems in the same condition with ClassBB::bound() in that both are template member function, ClassBB::THR is successfully accessed (I'm only talking about compile time, of course).

I'm still new to C++ especially in template architecture. Thanks!

Environment: Ubuntu 10.10, G++ 4.4.5 via Eclipse Indigo CDT

Error msg (only linker's part):

Building target: SampleEclipsePrj
Invoking: GCC C++ Linker
g++ -L/usr/local/lib -L/usr/lib -o "SampleEclipsePrj"  ./src/SampleEclipsePrjFinal/IntersectAngle.o ./src/SampleEclipsePrjFinal/ReadRealTime.o ./src/SampleEclipsePrjFinal/SampleEclipsePrj.o ./src/SampleEclipsePrjFinal/SampleEclipsePrjThread.o ./src/SampleEclipsePrjFinal/Slope.o ./src/SampleEclipsePrjFinal/Transform.o ./src/SampleEclipsePrjFinal/Utility.o ./src/SampleEclipsePrjFinal/main3_linux.o ./src/SampleEclipsePrjFinal/reader.o   -lcv -lcxcore -lhighgui
./src/SampleEclipsePrjFinal/SampleEclipsePrj.o: In function `ClassBB<double>::bound()':
/home/user/Documents/workspace_eclipse/SampleEclipsePrj/Includes/ClassBB.hpp:203: undefined reference to `ClassBB<double>::THR'
/home/user/Documents/workspace_eclipse/SampleEclipsePrj/Includes/ClassBB.hpp:204: undefined reference to `ClassBB<double>::THR'
/home/user/Documents/workspace_eclipse/SampleEclipsePrj/Includes/ClassBB.hpp:206: undefined reference to `ClassBB<double>::THR'
/home/user/Documents/workspace_eclipse/SampleEclipsePrj/Includes/ClassBB.hpp:207: undefined reference to `ClassBB<double>::THR'
collect2: ld returned 1 exit status
make: *** [SampleEclipsePrj] Error 1

**** Build Finished ****

Note: Got the same result both on Eclipse and terminal.

Code-B (snipped to show related part only):

#ifndef _BBOUND_H
#define _BBOUND_H

template<class T>
class ClassBB
{
        T *pMap;
        float u1, v1, u2, v2;
        int w, h;

        float converge(float sp, float ep, float steps, float fixedPt,
                float thr);
        static T THR;

    public:
        ClassBB() :
                pMap(NULL), u1(0), v1(0), u2(0), v2(0), w(0), h(0)
        {
        }
        ClassBB(float U1, float V1, float U2, float V2);
        static void setThreshold(T v);
    int bound();
        ~ClassBB();
};

template<class T>
ClassBB<T>::ClassBB(float U1, float V1, float U2, float V2)
{// do something
}

template<class T>
void ClassBB<T>::setThreshold(T v)
{
    ClassBB::THR = v;
}

//Converge
template<class T>
float ClassBB<T>::converge(float sp, float ep, float step, float fixedPt,
        float thr)
{// do something
    return point;
}
//The bound algorithm
template<class T>
int ClassBB<T>::bound()
{
    u2 = converge(0.75, 0.5, 0.03125, v2, ClassBB::THR);
    v2 = converge(0.25, 0.0, 0.03125, u2, THR); // Both don't work.
    return 1;
}

template<class T>
ClassBB<T>::~ClassBB()
{// do something
}

#endif

Code-C (instantiate the class):

#ifndef _SCENE_CLASSIFIER_H
#define _SCENE_CLASSIFIER_H
#include "ClassBB.hpp"

class ClassCC
{
        ClassBB<double> bb; //Branch and Bound

    public:
        ClassCC(int W = 0, int H = 0); 
        ~ClassCC(); 
};
#endif

Upvotes: 1

Views: 1176

Answers (2)

Diego Sevilla
Diego Sevilla

Reputation: 29021

You have to create the storage for the static variable. Just add:

template<class T> T ClassBB<T>::THR;

Note that for normal member variables, the storage is generated whenever a new instance of the template class is created. But for static members, a "static" place should be defined for them, hence the explicit definition.

Upvotes: 7

Cat Plus Plus
Cat Plus Plus

Reputation: 129984

You need to define static variables.

template<class T>
class ClassBB {
    // ...
    static T THR;
    // ...
};

template<class T>
T ClassBB<T>::THR;

Upvotes: 4

Related Questions