循环替换模板 [英] Template for loop replacement

查看:52
本文介绍了循环替换模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究可能在多维数组上循环的东西,但我遇到了一些模板问题.这是我正在尝试做的事情的想法:

I'm working on something that loops over a potentially multi-dimensional array and I am running into some template issues. Here is the idea of what I'm trying to do:

template<std::size_t D = 3>
class Deriv {
public:
    typedef typename boost::array<double, D> results_t;

    template<typename Iterator>
    results_t operator()(Iterator& objIterator)
    {
        double u;
        double um1;

        results_t derivs;

        for(results_t::index i = 0; i < D; ++i) {
           u = *objIterator;
           um1 = *(objIterator.left<i>(1));
           derivs[i] = u-um1;
        }
     }
   };
};

所以,它看起来有点令人困惑,但它使用了一个具有 leftright 模板方法的自定义迭代器,其中模板参数是向左移动或向左移动的维度就在,参数是偏移量.例如,如果 objIterator 指向 array[i][j][k],则 objIterator.left<0>(1) 返回array[i-1][j][k] 的迭代器.

So, it looks a little confusing, but it's using a custom iterator that has a left and right template method where the template parameter is the dimension to move left or right in and the argument is the offset. For example, if objIterator points to array[i][j][k], then objIterator.left<0>(1) returns an iterator to array[i-1][j][k].

显然我发布的内容不起作用,因为 i 不是编译时并且不能用作 left 的参数.我觉得在这里可以使用递归以某种方式通过替换 for 循环来实现这一点,但我不知道如何.

Obviously what I posted doesn't work because i is not compile time and can't be used as the parameter for left. I feel like recursion could be used here somehow to make this happen by replacing that for loop, but I don't know how.

有什么建议吗?

推荐答案

这是另一种方法:

template<std::size_t D = 3>
struct Deriv
{
    typedef typename boost::array<double, D> results_t;

private:
    template<std::size_t I>
    struct apply
    {
        template<typename Iterator>
        static void impl(results_t& derivs, Iterator& iter)
        {
            derivs[I] = *iter - *iter.template left<I>(1);
            apply<I + 1>::impl(derivs, iter);
        }
    };

    template<>
    struct apply<D>
    {
        template<typename Iterator>
        static void impl(results_t&, Iterator&) { }
    };

public:
    template<typename Iterator>
    results_t operator ()(Iterator& iter) const
    {
        results_t derivs;
        apply<0>::impl(derivs, iter);
        return derivs;
    }
};

我已经用 VC++ 2010 进行了测试,但我怀疑它可能无法在更符合标准的编译器上编译.如果你可以从 D-1 倒数到 0 而不是从 0D-1 倒数,那么以下应该没问题:

I've tested with VC++ 2010, but I suspect it may not compile on more conformant compilers. If you can count down from D-1 through 0 rather than up from 0 through D-1, then the following should be okay:

namespace detail
{
    template<std::size_t I>
    struct apply
    {
        template<typename ResultsT, typename Iterator>
        static void impl(ResultsT& derivs, Iterator& iter)
        {
            derivs[I] = *iter - *iter.template left<I>(1);
            apply<I - 1>::impl(derivs, iter);
        }
    };

    template<>
    struct apply<0>
    {
        template<typename ResultsT, typename Iterator>
        static void impl(ResultsT& derivs, Iterator& iter)
        {
            derivs[0] = *iter - *iter.template left<0>(1);
        }
    };
}

template<std::size_t D = 3>
struct Deriv
{
    typedef typename boost::array<double, D> results_t;

public:
    template<typename Iterator>
    results_t operator ()(Iterator& iter) const
    {
        results_t derivs;
        detail::apply<D - 1>::impl(derivs, iter);
        return derivs;
    }
};

这篇关于循环替换模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆