我将从代码开始,因为它更容易解释。
vector.cpp
template <typename T, unsinged int D>
class Vector
{
public:
Vector() {}
inline Vector<T, D> operator+(const Vector<T,D>& r)
{
Vector<T,D> result = T(0);
for(int i = 0; i < D; i++)
result[i] = (*this)[i] + r[i];
return result;
}
private:
T values[D];
}
template <typename T>
class Vector3 : public Vector<T, 3>
{
// Initialization constructor etc..
}
main.cpp
int main(int argc, char** args)
{
Vector3<float> vec1 = Vector3<float>(1.0f, 2.0f, 3.0f);
Vector3<float> vec2 = Vector3<float>(1.0f, 2.0f, 3.0f);
Vector3<float> res;
res = vec1 + vec2; // Here's the error
return 1;
}
出于某种原因,我在指示的行中收到错误消息,没有运算符“=”匹配这些操作数,操作数类型为 Vector3<float> = Vector<float, 3U>
.如果我将变量“res”声明为 Vector<float, 3> res;
有用。考虑到它继承了类“Vector”的定义,我不明白为什么会这样。有人可以帮我解决这个问题吗,我最好不要为所有派生类重新编写运算符重载函数就可以完成这项工作。我也有类似的矩阵实现。
提前谢谢你。
干杯。
最佳答案
这vec1 + vec2
调用父类的 operator+
,它返回一个父类类型的对象。您不能分配 Vector<float, 3U>
的对象到 Vector3<float>
类型的对象.
int main(int argc, char** args)
{
Vector<float, 3U> v;
Vector3<float> res;
res = v; // Here's the error
}
你可以这样做:
int main(int argc, char** args)
{
Vector3<float> vec1 = Vector3<float>(1.0f, 2.0f, 3.0f);
Vector3<float> vec2 = Vector3<float>(1.0f, 2.0f, 3.0f);
Vector<float, 3U> res = vec1 + vec2;
}
我想说为此尝试使用继承可能不是最好的主意。如果您可以使用 C++11,那么类型别名可能会更好:
template <typename T, unsinged int D>
class Vector
{
template<typename... Args> Vector(Args &&...args)
: values{std::forward<Args>(args)...}
{}
// ...
};
template<typename T>
using Vector3 = Vector<T, 3>;
i have overloaded '[]', '==' and '!=' and it seems to work without a problem,
问题是 operator+
您正在返回父类型 Vector<float,3U>
, 然后尝试在子类型 Vector3<float>
中使用该类型是必需的。
与 operator[]
你大概会回来 T&
然后在 T&
中使用它是必须的。和 operator!=
和 operator==
你回来了bool
并在 bool
中使用它是必须的。你看得到差别吗?你明白为什么吗:
Vector3<float> res = Vector3<float>();
作品和
Vector3<float> res = Vector<float, 3U>();
不是吗?
Can you please explain further on what type aliases are, and how it can improve the above implementation, and why it would.
您可以在 many 中了解它们的内容。 places .对于您的使用而言,它们的重要之处在于它们不会创建新类型,它们只是创建一种新方法来引用先前声明的类型。
因此,例如,您的继承基于 Vector3
代码 Vector3<float> res = Vector<float, 3U>();
会失败,但如果Vector3
是一个类型别名:
template<typename T> using Vector3 = Vector<T, 3U>;
然后是代码Vector3<float> res = Vector<float, 3U>();
将会成功,因为左右两侧的类型不再不匹配:使用类型别名意味着 Vector3<float>
不是 Vector<float, 3U>
的继承 ,它是类型 Vector<float, 3U>
.
关于C++ 运算符重载和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26315909/