Reputation: 47
I am using Xcode and I have provided two headers below: Spheres.h and Vector3.h which both are suppose to be templates. Vector3.h compiles without any errors.
Spheres.h do not compile and returns this warning: "Expected ')'"
and points to:
Sphere(const Vector3<T>& c,const float r);
^
This error occurs at any place inside Sphere.h where I have a Vector<T>
. If I remove <T>
the code can compile, I do not understand. Why? I want to be able to initialise Vector3<T>
with same template<typename T>
as Sphere<T>
.
Please help!
Sphere.h
#ifndef SPHERE
#define SPHERE
#include "Vector3.h"
template <typename T>
class Sphere
{
public:
// Constructors
// Default
Sphere();
// Copy
Sphere(const Sphere<T>& sphere);
Sphere(const Vector3<T>& c, const float r);
// Destructor
~Sphere();
// Get properties
const Vector3<T>& GetCenter() const;
const float& GetRadius() const;
// Set Properties
void SetCenter(const Vector3<T>& vector);
void SetRadius(const float& r);
// Methods
// Calculate sphere area: A = 4 * PI * r^2
const float GetArea() const;
// Calculate sphere volume: V = (4 * PI * r^3) / 3
const float GetVolume() const;
// Return if given point of vector3 is within sphere
const bool PointIntersect(const Vector3<T>& point) const;
bool Overlap(const Sphere<T>& sphere);
// Tries to load data from a string
bool Load(std::string string) const;
// Operators
// Assignment operator
Sphere<T>& operator=(const Sphere<T>& sphere);
// Less than operator <
bool operator<(const Sphere<T>& s) const;
// Greater than operator >
bool operator>(const Sphere<T>& s) const;
// Less or equal operator <=
bool operator<=(const Sphere<T>& s) const;
// Greater or equal operator >=
bool operator>=(const Sphere<T>& s) const;
// Equal operator ==
bool operator ==(const Sphere<T>& s) const;
// Not equal operator !=
bool operator!=(const Sphere<T>& s) const;
// Print a sphere to console with cout
friend std::ostream& operator<<(std::ostream& out, const Sphere<T>& s);
private:
T radius;
Vector3<T> center;
};
// Implementation
// Constructor
// Default
template<typename T>
Sphere<T>::Sphere()
{
// Created empty sphere
}
// Copy
template<typename T>
Sphere<T>::Sphere(const Sphere<T>& sphere)
{
this->SetPosition(sphere.GetPosition());
this->SetRadius(sphere.GetRadius());
this->SetCenter(sphere.GetCenter());
}
template<typename T>
Sphere<T>::Sphere(const Vector3<T>& center,const float radius)
{
this->SetPosition(center);
this->radius = radius;
}
// Destructor
template<typename T>
Sphere<T>::~Sphere()
{
// Nothing to delete.
}
// Properties
// Get
template<typename T>
const Vector3<T>& Sphere<T>::GetCenter() const
{
return center;
}
template<typename T>
const float& Sphere<T>::GetRadius() const
{
return radius;
}
// Set
template<typename T>
void Sphere<T>::SetCenter(const Vector3<T>& vector)
{
this->SetPosition(vector);
}
template<typename T>
void Sphere<T>::SetRadius(const float& r)
{
radius = r;
}
// Methods
// Calculate sphere area: A = 4 * PI * r^2
template<typename T>
const float Sphere<T>::GetArea() const
{
float temp = 4 * pi * powf(this->GetRadius(), 2);
return temp;
}
// Calcutate sphere volume: V = (4 * PI * r^3) / 3
template<typename T>
const float Sphere<T>::GetVolume() const
{
float temp = (4 * pi * powf(radius, 3))/3;
return temp;
}
// Return if given point of vector3 is within sphere
template<typename T>
const bool Sphere<T>::PointIntersect(const Vector3<T>& point) const
{
if (point.GetDistance(this->GetCenter(), point) >= this->radius)
{
return true;
}
return false;
}
template<typename T>
bool Sphere<T>::Overlap(const Sphere<T>& sphere)
{
// Calculate the distance between the two spheres
float distance = Vector3::GetDistance(sphere.GetCenter(), this->GetCenter());
// Calculate the length of both radiances
float radiusSum = sphere.radius + this->radius;
// if the length of radiance is greater than the distace -> there is a overlap
if (radiusSum > distance)
return true;
return false;
}
// Tries to load data from a string
template<typename T>
bool Sphere<T>::Load(std::string string) const
{
return false;
}
// Operators
// Asignment operator
template<typename T>
Sphere& Sphere<T>::operator=(const Sphere<T>& sphere)
{
this->SetCenter(sphere.GetCenter());
this->radius = sphere.radius;
return *this;
}
// Less than operator <
template<typename T>
bool Sphere<T>::operator<(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 < v2)
return true;
return false;
}
// Greater than operator >
template<typename T>
bool Sphere<T>::operator>(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 > v2)
return true;
return false;
}
// Less or equal operator <=
template<typename T>
bool Sphere<T>::operator<=(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 < v2)
return true;
if (v1 == v2)
return true;
return false;
}
// Greater or equal operator >=
template<typename T>
bool Sphere<T>::operator >=(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 > v2)
return true;
if (v1 == v2)
return true;
return false;
}
// Equal operator ==
template<typename T>
bool Sphere<T>::operator ==(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 == v2)
return true;
return false;
}
// Not equal operator !=
template<typename T>
bool Sphere<T>::operator !=(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 != v2)
return true;
return false;
}
// Print a sphere to console with cout
template<typename T>
std::ostream& operator<<(std::ostream& out, const Sphere<T>& s)
{
std::cout << "c:(" << s.GetCenter() << ") r:" << s.GetRadius();
return out;
}
#endif
Vector3.h
#ifndef VECTOR3
#define VECTOR3
// IO standard library
#include <iostream>
template<typename Type>
class Vector3
{
public:
// Constructor
Vector3(const Type& x, const Type& y, const Type& z);
// Copy constructor
Vector3(const Vector3<Type>& v);
// Destructor
~Vector3();
// Get properties
const Type& GetX() const;
const Type& GetY() const;
const Type& GetZ() const;
// Set properties
void SetX(const Type& value);
void SetY(const Type& value);
void SetZ(const Type& value);
// Methods
// Return length of the vector3<Type>
const float GetLength() const;
// Return the distance between two vector3<type>
const float GetDistance(const Vector3<Type>& v1, const Vector3<Type>& v2) const;
// Operators
// Assignment =
Vector3<Type>& operator=(const Vector3<Type>& v);
// Addition
Vector3<Type> operator+(const Vector3<Type>& v);
// Subtraction
Vector3<Type> operator-(const Vector3<Type>& v);
// Scalar product
float operator*(const Vector3<Type>& v);
// Multiplication
Vector3<Type> operator*(const float& s);
// Friend multiplication
friend Vector3<Type> operator*(const float& s, const Vector3<Type>& v);
// Cout: printing a vector3 to console
friend std::ostream& operator<<(std::ostream& out, const Vector3<Type>& v);
private:
Type x;
Type y;
Type z;
};
// Template implementation
// Constructor
template<typename Type>
Vector3<Type>::Vector3(const Type& x, const Type& y, const Type& z)
{
this->SetX(x);
this->SetY(y);
this->SetZ(z);
}
// Copy constructor
template<typename Type>
Vector3<Type>::Vector3(const Vector3<Type>& v)
{
this->SetX(x);
this->SetY(y);
this->SetZ(z);
}
// Destructor
template<typename Type>
Vector3<Type>::~Vector3<Type>()
{
// Nothin to delete
}
// Get Properties
template<typename Type>
const Type& Vector3<Type>::GetX() const
{
return this->x;
}
template<typename Type>
const Type& Vector3<Type>::GetY() const
{
return this->y;
}
template<typename Type>
const Type& Vector3<Type>::GetZ() const
{
return this->z;
}
// Set properties
template<typename Type>
void Vector3<Type>::SetX(const Type& value)
{
this->x = value;
}
template<typename Type>
void Vector3<Type>::SetY(const Type& value)
{
this->x = value;
}
template<typename Type>
void Vector3<Type>::SetZ(const Type& value)
{
this->x = value;
}
// Methods
// Return length of the vector3<Type>
template<typename Type>
const float Vector3<Type>::GetLength() const
{
float length = 0;
length = sqrtf(powf(x,2) + powf(y,2) + powf(z,2));
return length;
}
// Return the distance between two vector3's
template<typename Type>
const float Vector3<Type>::GetDistance(const Vector3<Type>& v1, const Vector3<Type>& v2) const
{
return sqrtf(powf((v2.x - v1.x), 2) +
powf((v2.y - v1.y), 2) +
powf((v2.z - v1.z), 2) );
}
// Operators
// Assignment
template<typename Type>
Vector3<Type>& Vector3<Type>::operator=(const Vector3<Type>& v)
{
this->SetX(v.x);
this->SetY(v.y);
this->SetZ(v.z);
return *this;
}
// Addition
template<typename Type>
Vector3<Type> Vector3<Type>::operator+(const Vector3<Type>& v)
{
Type x, y, z;
x = this->x + v.x;
y = this->y + v.y;
z = this->z + v.z;
Vector3<Type> temp(x, y, z);
return temp;
}
// Subtraction
template<typename Type>
Vector3<Type> Vector3<Type>::operator-(const Vector3<Type>& v)
{
Type x,y,z;
x = this->x - v.x;
y = this->y - v.y;
z = this->z - v.z;
Vector3<Type> temp(x, y, z);
return temp;
}
// Scalar product
template<typename Type>
float Vector3<Type>::operator*(const Vector3<Type>& v)
{
float scalarP = (this->GetX() * v.x) + (this->GetY() * v.y) + (this->GetZ() * v.z);
return scalarP;
}
template<typename Type>
Vector3<Type> Vector3<Type>::operator*(const float& s)
{
Vector3 temp(this->GetX() * s, this->GetY() * s, this->GetZ() * s);
return temp;
}
template<typename Type>
Vector3<Type> operator*(const float& s, const Vector3<Type>& v)
{
Vector3<Type> temp(v.x * s, v.y * s, v.z * s);
return temp;
}
// Cout: printing a vector3 to console
template<typename Type>
std::ostream& operator<<(std::ostream& out, const Vector3<Type>& v)
{
std::cout << "x:" << v.x
<< " y:" << v.y
<< " z:" << v.z;
return out;
}
#endif
Upvotes: 2
Views: 159
Reputation: 13897
The following compiles fine on gcc. Other than fixing the obvious syntax errors, I've also modified the constructors to fully initialize the object. Other possible solutions are to give Vector3 a default constructor (such that it can have a default initial value), or make center
a Vector3<T>*
.
#ifndef SPHERE
#define SPHERE
#include "vector3.h"
template <typename T>
class Sphere
{
public:
// Constructors
// Default
Sphere();
// Copy
Sphere(const Sphere<T>& sphere);
Sphere(const Vector3<T>& c, const float r);
// Destructor
~Sphere();
// Get properties
const Vector3<T>& GetCenter() const;
const float& GetRadius() const;
// Set Properties
void SetCenter(const Vector3<T>& vector);
void SetRadius(const float& r);
// Methods
// Calculate sphere area: A = 4 * PI * r^2
const float GetArea() const;
// Calculate sphere volume: V = (4 * PI * r^3) / 3
const float GetVolume() const;
// Return if given point of vector3 is within sphere
const bool PointIntersect(const Vector3<T>& point) const;
bool Overlap(const Sphere<T>& sphere);
// Tries to load data from a string
bool Load(std::string string) const;
// Operators
// Assignment operator
Sphere<T>& operator=(const Sphere<T>& sphere);
// Less than operator <
bool operator<(const Sphere<T>& s) const;
// Greater than operator >
bool operator>(const Sphere<T>& s) const;
// Less or equal operator <=
bool operator<=(const Sphere<T>& s) const;
// Greater or equal operator >=
bool operator>=(const Sphere<T>& s) const;
// Equal operator ==
bool operator ==(const Sphere<T>& s) const;
// Not equal operator !=
bool operator!=(const Sphere<T>& s) const;
// Print a sphere to console with cout
friend std::ostream& operator<<(std::ostream& out, const Sphere<T>& s);
private:
T radius;
Vector3<T> center;
};
// Implementation
// Constructor
// Default
template<typename T>
Sphere<T>::Sphere()
: radius(0), center(Vector3<T>(0,0,0))
{
// Created empty sphere
}
// Copy
template<typename T>
Sphere<T>::Sphere(const Sphere<T>& sphere)
: radius(sphere.radius), center(sphere.center)
{
}
template<typename T>
Sphere<T>::Sphere(const Vector3<T>& center, const float radius)
: radius(radius), center(center)
{
}
// Destructor
template<typename T>
Sphere<T>::~Sphere()
{
// Nothing to delete.
}
// Properties
// Get
template<typename T>
const Vector3<T>& Sphere<T>::GetCenter() const
{
return center;
}
template<typename T>
const float& Sphere<T>::GetRadius() const
{
return radius;
}
// Set
template<typename T>
void Sphere<T>::SetCenter(const Vector3<T>& vector)
{
this->SetPosition(vector);
}
template<typename T>
void Sphere<T>::SetRadius(const float& r)
{
radius = r;
}
// Methods
const float pi = 3.14;
// Calculate sphere area: A = 4 * PI * r^2
template<typename T>
const float Sphere<T>::GetArea() const
{
float temp = 4 * pi * powf(this->GetRadius(), 2);
return temp;
}
// Calcutate sphere volume: V = (4 * PI * r^3) / 3
template<typename T>
const float Sphere<T>::GetVolume() const
{
float temp = (4 * pi * powf(radius, 3))/3;
return temp;
}
// Return if given point of vector3 is within sphere
template<typename T>
const bool Sphere<T>::PointIntersect(const Vector3<T>& point) const
{
if (point.GetDistance(this->GetCenter(), point) >= this->radius)
{
return true;
}
return false;
}
template<typename T>
bool Sphere<T>::Overlap(const Sphere<T>& sphere)
{
// Calculate the distance between the two spheres
float distance = Vector3<T>::GetDistance(sphere.GetCenter(), this->GetCenter());
// Calculate the length of both radiances
float radiusSum = sphere.radius + this->radius;
// if the length of radiance is greater than the distace -> there is a overlap
if (radiusSum > distance)
return true;
return false;
}
// Tries to load data from a string
template<typename T>
bool Sphere<T>::Load(std::string string) const
{
return false;
}
// Operators
// Asignment operator
template<typename T>
Sphere<T>& Sphere<T>::operator=(const Sphere<T>& sphere)
{
this->SetCenter(sphere.GetCenter());
this->radius = sphere.radius;
return *this;
}
// Less than operator <
template<typename T>
bool Sphere<T>::operator<(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 < v2)
return true;
return false;
}
// Greater than operator >
template<typename T>
bool Sphere<T>::operator>(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 > v2)
return true;
return false;
}
// Less or equal operator <=
template<typename T>
bool Sphere<T>::operator<=(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 < v2)
return true;
if (v1 == v2)
return true;
return false;
}
// Greater or equal operator >=
template<typename T>
bool Sphere<T>::operator >=(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 > v2)
return true;
if (v1 == v2)
return true;
return false;
}
// Equal operator ==
template<typename T>
bool Sphere<T>::operator ==(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 == v2)
return true;
return false;
}
// Not equal operator !=
template<typename T>
bool Sphere<T>::operator !=(const Sphere<T>& s) const
{
float v1 = this->GetVolume();
float v2 = s.GetVolume();
if (v1 != v2)
return true;
return false;
}
// Print a sphere to console with cout
template<typename T>
std::ostream& operator<<(std::ostream& out, const Sphere<T>& s)
{
std::cout << "c:(" << s.GetCenter() << ") r:" << s.GetRadius();
return out;
}
#endif
Upvotes: 1
Reputation: 5665
It is because your class Sphere
requires Vector3
as template class. Like here:
~Sphere();
// Get properties
const Vector3<T>& GetCenter() const;
const float& GetRadius() const;
// Set Properties
But when you provide Sphere
with Vector3<T>
it will result in someting like this Vector3<T><T>
Upvotes: 0