我有这个类来分解N维向量空间上的常见操作:
template <unsigned int N>
struct BaseVector
{
float m_data[N];
// Common operations like dot product, magnitude, test for unity, etc.
};
注意:我真的想要尽可能多地分解代码,以尽量减少文档和测试的数量。
现在,我派出了两个类:
// 3D geometric vectors
struct Vector3 : public BaseVector<3>
{
Vector3 Cross(const Vector3& other);
// ...
};
// Quaternions are a particular kind of vector space
struct Quaternion : public BaseVector<4>
{
void Interpolate(const Quaternion& start, const Quaternion& end, ...);
// ...
};
这些类对于加法和标量乘法(组件操作)的行为类似;所以,我想在基础矢量类中对operator+=()
和operator*=()
进行分解。
我的问题是:如何返回正确类型的引用?
template <unsigned int N>
struct BaseVector
{
??? & operator+=(const BaseVector& other)
{
transform(m_data, m_data+N, other.m_data, m_data, plus<float>());
return ???
}
};
到目前为止我所有的想法(列在下面)并不令人满意,我希望得到一些建议,谢谢!
创意#1:使用C ++协变返回类型机制。但是,我必须在派生类中重载这些运算符 - 我是对的吗? (这意味着对我进行重复测试。)
创意#2:转到模板?
template <unsigned int N>
struct BaseVector
{
template <typename T2>
T2 & operator+=(const T2& other)
{
transform(...);
return *this; // THIS IS WRONG! I'm trying to "upcast"
}
};
创意#3:将代码分解为基本向量中的私有成员,但后来我必须在派生类中添加更多函数(以及更多要测试的东西)
template <unsigned int N>
struct BaseVector
{
private:
void DoOperatorPlus(const BaseVector& other) { transform(...); }
};
struct Vector4 : public BaseVector<4>
{
Vector4& operator+=(const Vector4& other)
{
DoOperatorPlus(other);
return *this;
}
};
答案 0 :(得分:3)
您实际上可以尝试使用CRTP
我们的想法是为您的派生类的基类提供一个模板参数:
template <unsigned int N, typename Derived>
struct BaseVector
{
Derived & operator+=(const Derived& other)
{
transform(m_data, m_data+N, other.m_data, m_data, plus<float>());
return static_cast<Derived&>(*this);
}
};
我对退货声明并不是100%肯定,但这应该会给你一个想法。