1

So I am writing a particle accelerator code for a c++ class, and Im having trouble with the initial class set up Im being asked to use. The professor wants us to use templates for the class, but when I try to implement them, I receive a number of errors. For instance:

#include <iostream>
#include <cmath>

using namespace std;
template <class Type>
class ThreeVector {
private:
    Type mx;
    Type my;
    Type mz;
public:
    ThreeVector();
    ThreeVector(Type x=0, Type y=0, Type z=0);


};

ThreeVector<Type>::ThreeVector() {
    Type mx=0;
    Type my=0;
    Type mz=0;
}
ThreeVector<T>::ThreeVector(Type x, Type y, Type z) {
    mx=x;
    my=y;
    mz=z;
}

is part of my header file (the class is required to be in a header file). When I run my program (can provide if needed), it gives me the following errors:

ThreeVector.h:30:13: error: ‘Type’ was not declared in this scope

ThreeVector.h:30:17: error: template argument 1 is invalid

ThreeVector.h: In function ‘int ThreeVector()’: ThreeVector.h:30:32: error: ‘int ThreeVector()’ redeclared as different kind of symbol

ThreeVector.h:6:7: note: previous declaration ‘template class ThreeVector’

ThreeVector.h:31:2: error: ‘Type’ was not declared in this scope

ThreeVector.h:32:7: error: expected ‘;’ before ‘my’

ThreeVector.h:33:7: error: expected ‘;’ before ‘mz’

ThreeVector.h: At global scope: ThreeVector.h:35:13: error: ‘Type’ was not declared in this scope

These problems did not exist before I started using the template, i.e., if I explicitly define all variable types, my class works fine. So, Im not really sure what is wrong with my template definition? If anyone could help, Id be really appreciative.

Thanks!

5
  • Which constructor should be called if no arguments are given? Commented Apr 26, 2015 at 22:35
  • Try putting template<class T> in front of the methods declared outside the class. (Replace T with whatever specifier is inside the template arguments.) Commented Apr 26, 2015 at 22:36
  • sorry, quick correction: the one instance of ThreeVectoor<T> was changed to ThreeVector<Type>.. Also, isnt template<class Type> already declared outside the class? Commented Apr 26, 2015 at 22:40
  • template<...> applies only to the immediately following declaration or definition. Commented Apr 26, 2015 at 22:41
  • I did not know that. Thank you for the clarification, chris, it seems to be working now! Commented Apr 26, 2015 at 22:44

2 Answers 2

2

You have to declare template arguments for methods that are part of a template class and yet are defined outside of the class definition. So to make your function definitions you have to do this:

template<class Type>
ThreeVector<Type>::ThreeVector() {
    mx=0;
    my=0;
    mz=0;
}

template<class Type>
ThreeVector<T>::ThreeVector(Type x, Type y, Type z) {
    mx=x;
    my=y;
    mz=z;
}

This is because the templated type is not available to the method declarations when they are outside of the class definition. To fix this you have to add a template< ... > with the same arguments as for the original class.

Also, you should use initializer lists to initialize members. That would make your constructors look like this:

template<class Type>
ThreeVector<Type>::ThreeVector() : 
    mx(0),
    my(0),
    mz(0)
{

}
Sign up to request clarification or add additional context in comments.

Comments

1
  1. You forgot to add

    template <typename Type>
    

    Before the function definition.

  2. Remove Type from the body of the function. When you add Type, you are declaring three function variables that are not related to the class members.

template <typename Type>
ThreeVector<Type>::ThreeVector() {
    mx=0;
    my=0;
    mz=0;
}

You can make it better by initializing the member using the initializer list syntax:

template <typename Type>
ThreeVector<Type>::ThreeVector() : mx(0), my(0), mz(0) { }

2 Comments

We were not introduced to initializer list syntax, what exactly does it do differently than the code I posted above? Just want to better understand for future use!
@RossBauer, It initializes the members instead of doing default initialization and then assigning to them later. The latter doesn't even work in all cases, like if it's a class with no default constructor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.