0

I Have the following code in Student.h

#ifndef _student_h_
#define _student_h_

template  <class T>
class Student
{
public:
    Student();
    ~Student();
    void setWage(float hourlyWage);
    void addHours(float hoursWorked);
    bool pay();
    bool writeCheck(float value);
    float getTotalEarnings();
    float getStudentCut();
    float getSwauCut();
    float getWage();
private:
    float wage;
    float hours;
    float swauCut;
    float studentCut;
    float totalEarnings;
};
#include "student.tpp" //Works with .tpp, errors with .cpp

#endif

As im trying to separate my code I attempted to place the following code into both a .cpp and a .tpp for testing.

#pragma once
#include "stdafx.h"
#include "Student.h"

template <class T>
Student<T>::Student()
{
    wage = 0.0f;
    hours = 0.0f;
    swauCut = 0.0f;
    studentCut = 0.0f;
    totalEarnings = 0.0f;
}

template <class T>
Student<T>::~Student()
{
}

template <class T>
void Student<T>::setWage(float hourlyWage)
{
    wage = hourlyWage;
}

template <class T>
void Student<T>::addHours(float hoursWorked)
{
    hours += hoursWorked;
}
template <class T>
bool Student<T>::pay()
{
    if (hours == 0 || wage == 0)
        return false;
    studentCut += .25*(hours * wage);
    swauCut += .75*(hours * wage);
    totalEarnings += hours * wage;
    hours = 0.0f;
    return true;
}
template <class T>
bool Student<T>::writeCheck(float value)
{
    if (value < studentCut){
        studentCut -= value;
        return true;
    }

    return false;
}
template <class T>
float Student<T>::getTotalEarnings()
{
    return totalEarnings;
}
template <class T>
float Student<T>::getStudentCut()
{
    return studentCut;
}
template <class T>
float Student<T>::getSwauCut()
{
    return swauCut;
}
template <class T>
float Student<T>::getWage()
{
    return wage;
}

My issue is that if I use the .cpp file and comment out the tpp file I get all sorts of errors. However if I just #include Student.tpp the files compile fine and work. I was under the impression that cpp and tpp were relatively the same?

The errors im getting are:

Error1  error C2995: 'Student<T>::Student(void)' : function template has already been defined   c:\users\aurelib.cs\desktop\studentproject\studentproject\student.cpp   13  1   StudentProject
Error2  error C2995: 'Student<T>::~Student(void)' : function template has already been defined  c:\users\aurelib.cs\desktop\studentproject\studentproject\student.cpp   18  1   StudentProject

.... for all the functions.

If I remove the #include "Student.h" from the .cpp file I get Syntax errors.

I am using Visual Studios. And like I said I have no problem when I #include "Student.tpp" at the bottom of the template. But when I use the same code and #include "Student.cpp" instead.

Thanks so much in advance!

NetVipeC
  • 4,402
  • 1
  • 17
  • 19
Brent Aureli
  • 463
  • 6
  • 21
  • Remove all the ``s. But be advised that template code shouldn't be in a `.cpp ` file, unless it's included from a header, which might cause more confusion than joy. But why did you make that class a template in the first place? I can't see the template parameter being used anywhere. – Biffen Sep 25 '14 at 16:59
  • Why should `Student` be a template class in 1st place? I can't spot any declaration using a `typename T` anywhere. Look's you have an XY-problem here. – πάντα ῥεῖ Sep 25 '14 at 17:02
  • It doesn't actually need to be. Its just a concept. The plan would be to accept a T object instead of float in WriteCheck function. Everything works, im just wondering why I cant use cpp and am forced into .tpp. And Tomas, I got the program running initially by reading that question. However I dont think it was explained why tpp is chosen over cpp. and why cpp doesn't appear to work at all – Brent Aureli Sep 25 '14 at 17:06
  • 1
    If you are including tpp in header file, it is the same as if you had implemented it in header file, so, compiler knows how the template is declared and implemented. And, as that question said, when compiler needs to instantiate any class from it, it needs to know how it implementation is done. Thats why it can't be in a compiled version, i.e. in cpp file – Amadeus Sep 25 '14 at 17:10
  • Thanks Tomas, I think I understand more clearly now. I appreciate the help! – Brent Aureli Sep 25 '14 at 18:07

1 Answers1

0

My guess is:

When you name the file containing the implementations of the class member functions Student.cpp, the compiler tries to compile it. When you name it Student.tpp, the compiler does not try to compile it.

In your files, Student.h #include's Student.cpp and Student.cpp #include's Student.h. When the proprocessor fleshes out the contents of Student.cpp, it ends up including the contents of the file twice. That's why you get the function template has already been defined error.

Ways to prevent it:

  1. Don't name the file Student.cpp. You can use Student.tpp, or a more descriptive name, Student_Impl.h.

  2. Add #include guards in the file, in addition to using #pragma once.

    #pragma once
    #ifndef _student_impl_h_
    #define _student_impl_h_
    
R Sahu
  • 204,454
  • 14
  • 159
  • 270