c++ - 类模板中的类模板

标签 c++ templates

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

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

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

此错误发生在 Sphere.h 中我有一个 Vector<T> 的任何地方.如果我删除 <T>代码可以编译,我看不懂。为什么?我希望能够初始化 Vector3<T>与相同template<typename T>作为Sphere<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

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

最佳答案

以下在 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

关于c++ - 类模板中的类模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21994364/

相关文章:

C++ OpenCV 图像通过套接字发送

c++ - 模板 : one for string and one for anything else 中的不同构造函数

c++ - constexpr 模板参数怪异

c++ - 删除模板类型

c++ - 将两个 uint16_t 数字相乘得到一个 int

c++ - 如何为 STL 容器的元素强制执行主键约束(如行为)

c++ - 为什么模板类的静态成员不是唯一的

sql-server - SQL Server 模板 - 如何转义小于字符?

c++ - 如何使用 Google Test 捕获段错误?

c++ - 是否无法在 Windows 95 和 Windows NT 4.0 中运行已编译的 C++ 应用程序?