tags:

views:

63

answers:

2

Why am I getting undefined references to the methods in this class when I call them? Will I be forced to include the implementation in the header file or is there another way to do this better?

class MathHelper
{
public:
    /*!
        Represents the ratio of the circumference of a circle to its diameter,
        specified by the constant, p. This value is accurate to 5 decimal places.
     */
    static const double pi = 3.14159;

    template <typename T> static const T modulo(const T &numerator, const T &denominator);
    static const double modulo(double numerator, double denominator);
    static const float modulo(float numerator, float denominator);
    template <typename T> static const T& clamp(const T &value, const T &min, const T &max);
    template <typename T> static const T wrap(const T &value, const T &min, const T &max);
    template <typename T> static bool isPowerOfTwo(T number);
    template <typename T> static T nearestPowerOfTwo(T number);
    static float aspectRatio(const QSize &size);
    template <typename T> static float aspectRatio(T width, T height);
    template <typename T> static T degreesToRadians(T degrees);
    template <typename T> static T radiansToDegrees(T radians);
    template <typename T> static T factorial(T n);

private:
    MathHelper() { }
};
+2  A: 

I think the explanation and answer to your question is this C++ faq lite answer and the next ones

Basically, as templates are patterns to instanciate, any code unit needing it must know how to instanciate it. Therefore, the simpliest way is to define your templates in header files (like boost does). The C++ faq lite give another way to do that. In my humble opinion, I think it is cumbersome...

my2c

neuro
I guess they go in the .h then. :( Thanks for your answer.
Jake Petroules
Yes. Same reaction when I discovered that :)
neuro
A: 

If we have the implementation defined in a corresponding .cpp file then we can use explicit instantiation so that compiler spits out the code that is being used by rest of the program.

Ex:- In the case of MathHelper if it is to be instantiated with int add the statement template MathHelper<int> in the corresponding .cpp file where the implementation is present.

There is a disadvantage with this methodolgy from the point of view that one must explicitly instantiate every time the template class is used with a different Parameter.

But we get all the benefits of seperating implemetation from the declaration , especially when the build sizes are huge.

pv