Data type error in templates

Please have a look at the following code.

Main.cpp

#include <iostream>
#include "Maximum.h"

using namespace std;

int main()
{

    Maximum max;

    int int1, int2, int3;

    cout << "Input three integers: ";
    cin >> int1 >> int2 >> int3;    
    cout << "The maximum value is: " << max.maximum(int1,int2,int3) << endl;




    double double1, double2, double3;

    cout << "Input three doubles: ";
    cin >> double1 >> double2, double3;    
    cout << "The maximum value is: " << max.maximum(double1, double2, double3) << endl;



    char char1, char2, char3;

    cout << "Input three char values: ";
    cin >> char1 >> char2 >> char3;
    cout << "The maximum value is: " << max.maximum(char1,char2,char3) << endl;

}

Maximum.h

template <class T>

class Maximum
{
    public:
        Maximum();
        T maximum(T value1, T value2, T value3);
};

Maximum.cpp

#include  <iostream>
#include "Maximum.h"

Maximum::Maximum()
{

}

    T Maximum::maximum(T value1, T value2, T value3)
    {
         T maximumValue = value1;

        if(value2>maximumValue)
        {
            maximumValue = value2;
        }

        if(value3>maximumValue)
        {
            maximumValue = value3;
        }


        return maximumValue;
    }

In maximum.cpp, it gives "'T' does not name a type" error. Since it is a user defined one, it might not identified it. How to solve this problem?

Answers


Member functions of class templates are themselves templates, and must be defined as such:

template <typename T>   // <-- Add this
Maximum::Maximum()
{
    // code
}

template <typename T>   // <-- Add this
T Maximum::maximum(T value1, T value2, T value3)
{
    // code
}

Once you've fixed that, you'll probably get some linker errors, because templates must (usually) be defined in every translation unit that uses them. The fix is to move the definitions into the header file. See this question for full details.


In your Maximum.cpp, your constructor and function should be called like this

template <class T>
Maximum<T>::Maximum()
{

}

template <class T>
T Maximum<T>::maximum(T value1, T value2, T value3)
{
        T maximumValue = value1;

    if(value2>maximumValue)
    {
        maximumValue = value2;
    }

    if(value3>maximumValue)
    {
        maximumValue = value3;
    }


    return maximumValue;
}

and in your main function you should call the class this way

 Maximum<int> max;

Your understanding of templates is wrong.

First, templates like this need a "user defined" type that is not known before usage. So they can't be found in .cpp files where everything must be known to the compiler (well, actually they can, but let's keep it simple for now).

As a consequence all your template code should be in header files. These header files must be shared with people using your code. For each CPP file in which your template header is included everything will be known and the compilation will be possible.

Then, you are using a class while what you need is a function.

So your final code should be limited to:

Maximum.h.

template<class T>
T Maximum(T v1, T v2, T v3) {
     // code in your member function
}

Main.cpp:

#include <iostream>
#include "Maximum.h"

using namespace std;

int main()
{
    double d1, d2, d3;
    double max = Maximum(d1, d2, d3);

    ...
}

First of all to make your code work try this code bellow. I made some changes.

Main.cpp

#include <iostream>
#include "Maximum.h"

using namespace std;

int main()
{

Maximum<char> max; // here you must explicitly specify template argument, I choosed "char"

int int1, int2, int3;

cout << "Input three integers: ";
cin >> int1 >> int2 >> int3;
cout << "The maximum value is: " << max.maximum(int1,int2,int3) << endl;




double double1, double2, double3;

cout << "Input three doubles: ";
cin >> double1 >> double2, double3;
cout << "The maximum value is: " << max.maximum(double1, double2, double3) << endl;



char char1, char2, char3;

cout << "Input three char values: ";
cin >> char1 >> char2 >> char3;
cout << "The maximum value is: " << max.maximum(char1,char2,char3) << endl;

}

Maximum.cpp

#include  <iostream>
#include "Maximum.h"
template <class T> // add this line
Maximum<T>::Maximum()
{

}
template <class T> // you must add this line
T Maximum<T>::maximum(T value1, T value2, T value3) // also here Maximum<T>:: and not Maximum::
{
     T maximumValue = value1;

    if(value2>maximumValue)
    {
        maximumValue = value2;
    }

    if(value3>maximumValue)
    {
        maximumValue = value3;
    }


    return maximumValue;
}

template class Maximum<char>;// you have to explicitly instantiate Maximum<char> for linking time.

You have to know that in Main.cpp there is no definition of the class template Maximum so even thou you called Maximum<char> no definition will be generated, because your class template definition of Maximum is inside Maximum.cpp. and because you didn't use MAximum<char> inside Maximum.cpp no definition will be generated inside Maximum.cpp for the linking time. for this reason you have to explicitly instantiate Maximum<char> for the linking time.


First, copy the code from maximum.cpp to the end of maximum.h, then remove maximum.cpp. The compiler has to see the code wherever the template is used, so template code should almost always be in the header where the template is defined.

Second, mark the definitions of the member functions (the code that you just copied) as templates:

template <class T>
Maximum<T>::Maximum() { }

etc.

Third, note that constructors cannot return values; the return statement in Maximum::Maximum(T value1, T value2, T value3) is illegal. Add a data element of type T and store the result there; then add an accessor so that users of this class can get the stored value.

Or follow the suggestion made in another answer and make this a function. That's a much better solution.


Need Your Help

Setting the "from" header field in Java MimeMessage not working correctly

java mime-message

For a web application I'm working on I made a method to send email notifications. The message has to come from a specific account, but I would like the "from" header field to read as an entirely

MS Access Import from Text File problems

ms-access vba database

I'm trying to import a text file into an access database. It's not one I've written myself but the spec for the delimited text file is set up properly and the file imports properly using the wizard...