1

我有这个类来分解 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;
    }
};
4

1 回答 1

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% 确定 return 声明,但这应该给你一个想法。

于 2012-10-11T07:54:20.080 回答