简体   繁体   English

类模板内的类模板

[英]Class template inside a class template

I am using Xcode and I have provided two headers below: Spheres.h and Vector3.h which both are suppose to be templates. 我正在使用Xcode,下面提供了两个标头:Spheres.h和Vector3.h,它们都应该是模板。 Vector3.h compiles without any errors. Vector3.h编译时没有任何错误。

Spheres.h do not compile and returns this warning: "Expected ')'" and points to: Spheres.h无法编译并返回以下警告: "Expected ')'"并指向:

Sphere(const Vector3<T>& c,const float r);
                     ^

This error occurs at any place inside Sphere.h where I have a Vector<T> . 这个错误发生在Sphere.h中我拥有Vector<T>任何地方。 If I remove <T> the code can compile, I do not understand. 如果删除<T>则代码可以编译,我不理解。 Why? 为什么? I want to be able to initialise Vector3<T> with same template<typename T> as Sphere<T> . 我希望能够使用与Sphere<T>相同的template<typename T>初始化Vector3<T> Sphere<T>

Please help! 请帮忙!

Sphere.h 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 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

The following compiles fine on gcc. 以下代码可以在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>* . 其他可能的解决方案是为Vector3提供默认的构造函数(这样它可以具有默认的初始值),或使centerVector3<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

It is because your class Sphere requires Vector3 as template class. 这是因为您的Sphere类需要将Vector3作为模板类。 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> 但是,当您为Sphere提供Vector3<T> ,将导致像Vector3<T><T>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM