固定尺寸矢量的任意调节

时间:2016-02-13 12:02:09

标签: c++ templates traits auto

对于模板等练习,我正在为任意数字维度实现固定大小的模板数学类型。

前提: 我有一个基础 rvec 类,用于抽象实现向量数学的 tvec 类(未显示或必需)所使用的数据。基类有两种形式 - 值类型和引用类型,通过使用布尔标志的模板特化来区分。

引用类型是我目前实现任意调配的解决方案。我正在使用traits来根据类型(指针或非指针)启用/禁用重载,但这对于我的混合所需的可变参数的部分特化效果不佳(它确实有效,但需要滥用特性和模板到我觉得自己并不能保持这种程度 - 我可以回到那个程度。)

问题:以下内容完全符合预期!有一件事真的让我烦恼。创建自动变量并将其分配给swizzle时,它会存储引用类型而不是存储value-type。我真的不希望最终用户能够创建引用类型。此数据结构应尽可能模拟或表现为POD。

仅存在引用类型,因此我可以从混合中进行方法链接。可悲的是,如果不使用汽车,一切正常。

template<unsigned S, typename T=float, bool B=false>
class rvec
{
    std::array<T, S> data;
public:
    float  operator[] (unsigned i) const { return data[i]; }
    float &operator[] (unsigned i)       { return data[i]; }

    // Returns reference-type!
    template<unsigned ...I, unsigned N = sizeof...(I)>
    rvec<N, T, true> swizzle()  { return{ {&data[I]...} }; }

    // Value-Type!
    template<unsigned ...I, unsigned N = sizeof...(I)>
    rvec<N, T> swizzle() const  { return{ { data[I]... } }; }

    rvec(const std::initializer_list<T> &d) { std::copy(d.begin(), d.end(), data.begin()); }
    rvec() {}
};

这是我的参考类型。它应该提供读取和写入,但我不希望用户有意或无意地将其存储在变量中。它应该只存在于方法链变化到调用swizzle的值类型。

我尝试对赋值/复制构造函数进行私有化,但编译器不会切换到使用正确的混合函数(来自value-type)或利用隐式类型转换(在reference-type中)。

template<unsigned S, typename T>
class rvec<S,T,true>
{
    std::array<T*, S> data;
    rvec(const std::initializer_list<T*> &d) { std::copy(d.begin(), d.end(), data.begin()); }

    template<unsigned N, typename T, bool B> friend class rvec;
    rvec &operator=(const rvec &o);
    rvec(const rvec &o);
public:
    // same access behavior as value-type
    float  operator[] (unsigned i) const { return *data[i]; }
    float &operator[] (unsigned i)       { return *data[i]; }
    // convert to value-type.
    operator rvec<S, T, false>()
    {
        rvec<S, T, false> r;
        for (unsigned i = 0; i < S; ++i)
            r[i] = *data[i];
        return r;
    }
    // write to the original values
    rvec &operator=(const rvec<S, T, false> &o)
    {
        for (unsigned i = 0; i < S; ++i)
            &data[i] = o[i];
    }

    template<unsigned ...I, unsigned N = sizeof...(I)>
    rvec<N, T, true> swizzle() const { return{ { data[I]... } }; }
};

什么是阻止我的参考类型出现在混合之外的好方法?我需要写访问权限并希望保持固定大小。

谢谢!

0 个答案:

没有答案