类模板内的类模板

Class template inside a class template

本文关键字:      更新时间:2023-10-16

我正在使用Xcode,我在下面提供了两个标题:Spheres.h和Vector3.h,它们都应该是模板。Vector3.h 编译没有任何错误。

Spheres.h 不编译并返回以下警告:"Expected ')'"并指向:

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

此错误发生在 Sphere.h 内我有Vector<T>的任何地方。如果我删除代码可以编译<T>,我不明白。为什么?我希望能够以与Sphere<T>相同的template<typename T>初始化Vector3<T>

请帮忙!

球体.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

矢量3.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

下面的编译在 gcc 上很好。除了修复明显的语法错误外,我还修改了构造函数以完全初始化对象。其他可能的解决方案是给 Vector3 一个默认构造函数(这样它可以有一个默认的初始值),或者center一个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

这是因为您的类Sphere需要Vector3作为模板类。像这里:

~Sphere();
// Get properties
const Vector3<T>& GetCenter() const;
const float& GetRadius() const;
// Set Properties

但是当你向Sphere提供Vector3<T>时,它会导致这样的事情Vector3<T><T>

相关文章:
  • 没有找到相关文章