我正在研究在一个潜在的多维数组上循环的东西,我遇到了一些模板问题。这是我正在尝试做的事情的想法:
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;
}
}
};
};
所以,它看起来有点困惑,但它使用了一个自定义迭代器,它有一个 left
和 right
模板方法,其中模板参数是要向左或向右移动的维度,参数是偏移量。例如,如果 objIterator
指向 array[i][j][k]
, 然后 objIterator.left<0>(1)
返回一个迭代器到 array[i-1][j][k]
.
显然我发布的内容不起作用,因为 i
不是编译时间,不能用作 left
的参数.我觉得这里可以通过替换 for 循环以某种方式使用递归来实现这一点,但我不知道如何实现。
有什么建议吗?
最佳答案
这是另一种方法:
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
而不是从 0
倒数到 D-1
,那么以下应该没问题:
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;
}
};
关于c++ - 循环替换模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10356384/