c++在模板编译错误中使用模板

C++ Using a Template in a Template Compiler Error

本文关键字:编译 c++ 错误      更新时间:2023-10-16

所以我第一次学习如何使用模板。我试图创建简化的向量和点类。不幸的是,我需要建模,一个点可以由一个向量和一个向量可以创建,由于两个点的减法。

我遇到的问题是我需要把文件包括在彼此。当我在我的点模板头文件中包含向量类时,我得到一个编译器错误,因为点类不再被识别为模板。

向量类(in Vector3D.h)

#include "Point3D.h"
template <class T>
class Vector3D
{
public:
    //Members
    T x,y,z;
    ... //more boring functions
    Point3D<T> operator+ (const Point3D<T>& pt)
    {
        Point3D <T> pt2(x + pt.x, y + pt.y, z + pt.z);
        return pt2;
    }
};

Point Class (in Point3D.h)

#include "Vector3D.h"
template <class K>
class Point3D
{
public:
    //Members
    K x,y,z;
    ...//boring functions of little importance
    // shifts point by a vector
    Point3D<K> operator+ (const Vector3D<K>& other)
    {
        return Point3D<K>(x + other.x, y + other.y, z + other.z);
    }
    //creates a vector from the differnce between two points
    Vector3D<K> operator- (const Point3D<K>& rhs)
    {
        return Vector3D<K>(x-lhs.x,y-lhs.y,z-lhs.z)
    }
};
现在我得到以下编译器错误(Intel c++ 15):
1>F:Dev ReposVascular ModelingRadiation Modeling ProjectsCGAL BOOST  INTEL project1Vector3D.h(197): error : Point3D is not a template
1>      Point3D<T> operator+ (const Point3D<T>& pt)
1>      ^
1>  
1>F:Dev ReposVascular ModelingRadiation Modeling ProjectsCGAL BOOST INTEL project1Vector3D.h(197): error : Point3D is not a template
1>      Point3D<T> operator+ (const Point3D<T>& pt)

我做错了什么?我想我是在尝试打破物理定律,创造某种循环。是解决方案,使分割文件的实现?

谢谢,

正如在注释中提到的,您希望使用前向声明。在模板类的情况下,它们看起来像这样:

template <class K> class Point3D; //before defining Vector3D
template <class T> class Vector3D; //before defining Point3D

假设你也正确地使用了include保护(如果你在这种情况下不使用include保护,头文件将无限期地相互包含,你会得到更奇怪的错误消息),这应该使所有内容都正确编译。与非模板类不同,您不必将方法的实现移到其他文件中,因为它们是在模板实例化时生成的,而不是在定义它们时生成的。

不过,作为附注,通常建议将二进制操作定义为独立的函数,而不是类成员,因为隐式转换的规则不同,而且更直观。因此,我建议这样做:
//shifting points by vectors
template <class T>
Point3D<T> operator+ (const Vector3D<T>& vec, const Point3D<T>& pt)
{
    return {vec.x + pt.x, vec.y + pt.y, vec.z + pt.z};
}
template <class T>
Point3D<T> operator+ (const Point3D<T>& pt, const Vector3D<T>& vec)
{
    return vec + pt;
}
//getting a vector from the difference of points
template <class T>
Vector3D<T> operator- (const Point3D<T>& a, const Point3D<T>& b)
{
    return {a.x - b.x, a.y - b.y, a.z - b.z};
}

这也使得这些函数的const正确性更加明显。如果你真的想做更多的工作(而且你使用的是c++ 11,我假设你现在使用的是c++ 11),你还可以将这些函数标记为constexpr,以便在常量表达式中使用向量/点操作。