静态循环

Met*_*ead 3 c++ boost stl c++11 c++-amp

我正在编写模板化的短矢量和小矩阵类,它们不限于具有2-3-4个元素,但可以具有任意数量的元素.

template <typename T, size_t N>
class ShortVector
{
public:

    ...

    template <size_t I> T& get() { return m_data[I]; }
    template <size_t I> const T& get() const { return m_data[I]; }

private:

    T m_data[N];
};
Run Code Online (Sandbox Code Playgroud)

我希望访问接口是静态的,这样我就可以专门使用内置的向量寄存器来支持类的大小.(可能它们是AVX,C++ AMP或OpenCL向量.)问题是为这个类编写所有理想的运算符(一元 - ,+, - ,*,/,点,长度......)需要很多模板递归,我甚至没有实现矩阵向量和矩阵 - 矩阵乘法,我将需要嵌套递归.

现在我有非成员朋友操作符和私有成员类,具有各种静态函数,如

template <size_t I, typename T1, typename T2> struct Helpers
{
    static void add(ShortVector& dst, const ShortVector<T1, N>& lhs, const ShortVector<T2, N>& rhs)
    {
        dst.get<I>() = lhs.get<I>() + rhs.get<I>();
        Helpers<I - 1, T1, T2>::add(dst, lhs, rhs);
    }

    ...
};
template <typename T1, typename T2> struct Helpers < 0, T1, T2 >
{
    static void add(ShortVector& dst, const ShortVector<T1, N>& lhs, const ShortVector<T2, N>& rhs)
    {
        dst.get<0>() = lhs.get<0>() + rhs.get<0>();
    }

    ...
};
Run Code Online (Sandbox Code Playgroud)

为所有操作员编写这样的静态函数和特殊化只是错了.以这种方式编写更复杂的操作非常容易出错.我正在寻找的是类似的东西

static_for< /*Whatever's needed to define something like a run-time for cycle*/, template <size_t I, typename... Args> class Functor>();
Run Code Online (Sandbox Code Playgroud)

或几乎任何让我省略大部分样板代码的东西.我已经开始编写这样一个类,但我无法通过合理的专业化来编译它.我觉得我仍然缺乏编写这样一个类(或函数)的技能.我查看了其他库,例如Boost MPL,但还没有完全致力于使用它.我也查看了std :: index_sequence,它也可能有用.

虽然std :: index_sequence似乎是最便携的解决方案,但它有一个我不愿意看的重大缺陷.最终这些类必须与SYCL兼容,这意味着我只能使用C++ 11,包括模板元编程技术.std :: integer_sequence是一个C++ 14 STL库的补充,虽然这种语言标准的限制只对语言特性有影响,但没有什么能阻止STL实现者在实现C++ 14 STL时使用C++ 14语言特性功能,因此使用C++ 14 STL功能可能不可移植.

我愿意接受建议,甚至是解决方案.

编辑

以下是我到目前为止的情况.这是我开始收集的模板元编程技巧的标题,而for循环将是下一个.帮助器需要一个函子,它具有运行索引作为它的第一个参数,并接受各种谓词.只要下一次迭代的谓词成立,它就会继续实例化仿函数.可以使运行索引增加任何数字,乘以数字等.

seh*_*ehe 5

您可以查看Boost Fusion的算法.

所需要的只是将您的类型调整为融合序列.

简单示例:Live On Coliru

#include <boost/array.hpp>
#include <boost/fusion/adapted.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/include/io.hpp>
#include <iostream>

int main()
{
    using namespace boost;

    boost::array<int, 4> iv4 { 1,2,3,4 };
    boost::array<double, 4> id4 { .1, .2, .3, .4 };

    auto r = fusion::transform(iv4, id4, [](auto a, auto b) { return a+b; });
    std::cout << r;
}
Run Code Online (Sandbox Code Playgroud)

打印:

(1.1 2.2 3.3 4.4)
Run Code Online (Sandbox Code Playgroud)