模板类中对operator +的未定义引用

时间:2015-03-01 01:38:01

标签: c++ templates operator-keyword undefined-reference

我试图为游戏制作一个简单的2D坐标矢量类,但是当重写operator +时我遇到了问题。向量使用模板来设置其X和Y值的数据类型,因此所有函数(包括运算符重载)都必须使用模板。所有成员函数都可以正常工作,但非成员函数会给我一个错误。

这是错误:

In function `ZNK13AxisAlignedBB8maxPointEv':
undefined reference to `Vector<double> operator+<double>(Vector<double> const&, Vector<double> const&)'

以下是给我错误的代码:

Vector2d AxisAlignedBB::maxPoint() const {
    return position + dimensions;
    //position and dimensions are both type Vector<double>
}

这是函数的声明:

template <typename T> class Vector {
    //class definition...
}


template<typename T>
Vector<T> operator+(const Vector<T>&, const Vector<T>&);

这是该功能的实现。据我所知,它应符合上述声明:

template<typename T> Vector<T> operator+(const Vector<T>& v1, const Vector<T>& v2){
    return v1.add(v2); //returns Vector<T>(v1.x + v2.x, v1.y + v2.y)
}

我也在我的游戏中使用SFML作为图形,所以为了确保,我查看了SFML / System / Vector2.hpp,它与我的矢量基本上完成相同的工作。这里有相同函数的版本,除了参数名称外,它看起来与我的相同:

template <typename T>
Vector2<T> operator +(const Vector2<T>& left, const Vector2<T>& right);

我无法访问SFML的功能实现,所以我无法检查以确保它是相同的。我之所以不使用SFML的载体,是因为它们不包含大小,交叉产品等功能。另外,我真的很懒惰而且不喜欢它们。我想把&#34; sf ::&#34;在一切之前。

编辑:Vector.h / .cpp

的全文

Vector.h:

#ifndef VECTOR_H
#define VECTOR_H

#include <SFML/System/Vector2.hpp>

template <typename T> class Vector {
public:
    T x;
    T y;

    Vector<T>() : x(0), y(0) {};

    Vector<T>(T ax, T ay) : x(ax), y(ay) {};

    ///Conversion from SFML vector of same type
    Vector<T>(const sf::Vector2<T>& v) : x(v.x), y(v.y) {};

    /**
     * Returns the magnitude of this Vector<T>.
     */
    T mag() const;

    /**
     * Returns the square of the magnitude of this Vector<T>, cutting
     * out an expensive sqrt() call.
     */
    T magSquared() const;

    /**
     * Returns the dot product of this and the given Vector<T>.
     */
    T dot(const Vector<T>&) const;

    /**
     * Returns the distance between this and the given Vector<T>.
     */
    T distance(const Vector<T>&) const;

    /**
     * Returns the square of the distance between this and the given Vector<T>,
     * cutting out an expensive sqrt() call.
     */
    T distanceSquared(const Vector<T>&) const;

    /**
     * Returns a new Vector<T> with the same coordinates.
     */
    Vector<T> clone() const;

    /**
     * Returns the resultant Vector<T> of adding the given Vector<T>.
     */
    Vector<T> add(const Vector<T>&) const;

    /**
     * Returns the resulting Vector<T> of subtracting the given Vector<T>.
     */
    Vector<T> sub(const Vector<T>&) const;

    /**
     * Returns the resulting Vector<T> of multiplying this Vector<T> by
     * the given scalar value.
     */
    Vector<T> mult(T) const;

    /**
     * Returns the projection of this Vector<T> onto the given axis.
     * In this function, this Vector<T> is the point to be projected
     * and the given Vector<T> is the axis.
     */
    Vector<T> proj(const Vector<T>&) const;

    /**
     * Returns the projection of the given Vector<T> on to this axis.
     * In this function, this Vector<T> acts as the axis and the given
     * Vector<T> is the point to be projected.
     */
    Vector<T> proj2(const Vector<T>&) const;

    /**
     * Revolves this Vector<T> about the origin by the given angle in radians.
     */
    Vector<T> revolve(T) const;

    /**
     * Revolves this Vector<T> about the given Vector<T>
     * by the given angle in radians.
     */
    Vector<T> revolveAbout(T, const Vector<T>&) const;

    /**
     * Returns the normalized version of this Vector<T>.
     */
    Vector<T> normalize() const;

    /**
     * Performs a 2D cross product with the given Vector<T>.
     */
    T crossVector(const Vector<T>&) const;

    /**
     * Performs a 2D cross product with the given scalar value.
     * This function performs the operation this X value.
     */
    Vector<T> crossScalar(T) const;

    /**
     * Performs a 2D cross product with the given scalar value.
     * This function performs the operation value X this.
     */
    Vector<T> crossScalar2(T) const;

    Vector<T>& operator+=(const Vector<T>& v){
        x += v.x;
        y += v.y;
        return *this;
    }

    Vector<T>& operator-=(const Vector<T>& v){
        x -= v.x;
        y -= v.y;
        return *this;
    }

    Vector<T>& operator*=(const T t){
        x *= t;
        y *= t;
        return *this;
    }

    Vector<T>& operator/=(const T t){
        x /= t;
        y /= t;
        return *this;
    }

    Vector<T> operator-(){
        return Vector(-x, -y);
    }

    ///Conversion from SFML vector of same type
    Vector<T>& operator=(const sf::Vector2<T>&);

    ///Conversion to SFML vector of same type
    operator sf::Vector2<T>();

protected:
private:
};

typedef Vector<double> Vector2d;
typedef Vector<float> Vector2f;
typedef Vector<int> Vector2i;

template<typename T> Vector<T> operator+(const Vector<T>& v1, const Vector<T>& v2){
    return Vector<T>(v1.x + v2.x, v1.y + v2.y);
}

template<typename T> Vector<T> operator-(const Vector<T>& v1, const Vector<T>& v2){
    return Vector<T>(v1.x - v2.x, v1.y - v2.y);
}

template<typename T> Vector<T> operator*(const Vector<T>& v, const T t){
    return Vector<T>(v.x * t, v.y * t);
}

template<typename T> Vector<T> operator*(const T t, const Vector<T>& v){
    return Vector<T>(v.x * t, v.y * t);
}

template<typename T> Vector<T> operator/(const Vector<T>& v, const T t){
    return Vector<T>(v.x / t, v.y / t);
}

#endif // VECTOR_H

Vector.cpp:

#include "Vector.h"
#include <cmath>

template<typename T> T Vector<T>::mag() const {
    return std::sqrt(magSquared());
}

template<typename T> T Vector<T>::magSquared() const {
    return std::pow(x, 2) + std::pow(y, 2);
}

template<typename T> T Vector<T>::dot(const Vector<T>& v) const {
    return (v.x * x) + (v.y * y);
}

template<typename T> T Vector<T>::distanceSquared(const Vector<T>& v) const {
    return sub(v).magSquared();
}

template<typename T> T Vector<T>::distance(const Vector<T>& v) const {
    return sub(v).mag();
}

template<typename T> Vector<T> Vector<T>::clone() const {
    return Vector(x, y);
}

template<typename T> Vector<T> Vector<T>::add(const Vector<T>& v) const {
    return Vector(x + v.x, y + v.y);
}

template<typename T> Vector<T> Vector<T>::sub(const Vector<T>& v) const {
    return Vector(x - v.x, y - v.y);
}

template<typename T> Vector<T> Vector<T>::mult(T t) const {
    return Vector(t * x, t * y);
}

template<typename T> Vector<T> Vector<T>::proj(const Vector<T>& axis) const {
    return axis.proj2(*this);
}

template<typename T> Vector<T> Vector<T>::proj2(const Vector<T>& point) const {
    T p = dot(point) / magSquared();
    return mult(p);
}

template<typename T> Vector<T> Vector<T>::revolve(T a) const {
    a += std::atan2(y, x);
    return Vector(mag() * std::cos(a), mag() * std::sin(a));
}

template<typename T> Vector<T> Vector<T>::revolveAbout(T a, const Vector<T>& v) const {
    return sub(v).revolve(a).add(v);
}

template<typename T> Vector<T> Vector<T>::normalize() const {
    return Vector(x / mag(), y / mag());
}

template<typename T> T Vector<T>::crossVector(const Vector<T>& v) const{
    return x * v.y - y * v.x;
}

template<typename T> Vector<T> Vector<T>::crossScalar(T t) const {
    return Vector(t * y, -t * x);
}

template<typename T> Vector<T> Vector<T>::crossScalar2(T t) const {
    return crossScalar(-t);
}

template<typename T> Vector<T>& Vector<T>::operator=(const sf::Vector2<T>& v){
    x = v.x;
    y = v.y;
    return *this;
}

template<typename T> Vector<T>::operator sf::Vector2<T>(){
    return sf::Vector2<T>(x, y);
}

0 个答案:

没有答案