【问题标题】:Inheritance from recursive template class从递归模板类继承
【发布时间】:2016-03-18 18:04:21
【问题描述】:

感谢递归模板,我正在尝试实现某种多维数组。

我的模板类的结构如下:

template< typename T, unsigned int D >
class MultiArray
{
public:
    MultiArray();

protected:
    std::vector< MultiArray< T, D - 1 > > VecSubarrays;
};

template< typename T >
class MultiArray< T, 0 >
{
public:
    MultiArray();

protected:
    T Item;
};

带有一些访问器、修饰符等

我想用T = double“特化”这个模板类,并添加一些特定的功能,比如运算符重载(+、-、+=、-=)。

所以我创建了这个模板类:

template< unsigned int D >
class MultiArrayDouble: public MultiArray< double, D >
{
public:
    MultiArrayDouble();

    template< unsigned int E >
        MultiArrayDouble< D >& operator+=(MultiArrayDouble< E > const& A_MAD);
    MultiArrayDouble< D >& operator+=(MultiArrayDouble< 0 > const& A_MAD);
};

我在哪里重载了operator+=(编辑:参见下面的实现)。

但是这个结构没有我期望的行为。我相信MultiArrayDouble&lt; D &gt; 对象的子数组只是MultiArrayDouble&lt; D - 1 &gt;。但是我递归编码operator+=,编译器说:

error: no match for 'operator+=' (operand types are 'MultiArray<double, 1u>' and 'const MultiArray<double, 1u>')

事实上,MultiArrayDouble&lt; D &gt; 对象的子数组是MultiArray&lt; double, D - 1 &gt;,其中operator+= 没有重载。

我想我可以通过从MultiArray&lt; double, D &gt;MultiArrayDouble&lt; D &gt; 的一些演员来解决这个问题,但我正在寻找一个优雅的解决方案。

我想我可以将子数组类型指定为模板参数,如下所示:

template< typename T, unsigned int D, template< typename, unsigned int, typename > typename U >
class MultiArray
{
public:
    MultiArray();

protected:
    std::vector< U< T, D - 1, ??? > > VecSubarrays;
};

U 替换为MultiArray 用于一般数组,或MultiArrayDouble 用于双数组。但是我不能写出确切的子数组类型(看“???”)……

这个问题有标准的解决方案吗?我应该避免从递归模板类继承吗?

谢谢。

编辑

operator+=的实现:

template< unsigned int D >
template< unsigned int E >
MultiArrayDouble< D >& MultiArrayDouble< D >::operator+=(MultiArrayDouble< E > const& A_MAD)
{
    for (unsigned int i = 0 ; i < this->Length() ; i++)
    {
        (*this)[i] += A_MAD[i];
    }
    return (*this);
}

template< unsigned int D >
MultiArrayDouble< D >& MultiArrayDouble< D >::operator+=(MultiArrayDouble< 0 > const& A_MAD)
{
    for (unsigned int i = 0 ; i < this->Length() ; i++)
    {
        (*this)[i] += A_MAD;
    }
    return (*this);
}

template<  >
MultiArrayDouble< 0 >& MultiArrayDouble< 0 >::operator+=(MultiArrayDouble< 0 > const& A_MAD)
{
    (*this) += A_MAD;
    return (*this);
}

注意事项:

  • 运算符operator[](unsigned int i)返回第i个子数组,即VecSubarrays[i]
  • 我已经实现了从 MultiArray&lt; T, 0 &gt;T&amp; 的隐式转换。

【问题讨论】:

  • 你能展示你的递归代码operator+=吗?

标签: c++ templates inheritance recursion


【解决方案1】:

我宁愿使用模板规范机制,而不是继承自MultiArray 的特定类MultiArryDouble。指定MultiArray&lt;double, D&gt; 会是更好的方法。

一个缺点是你必须重复整个课程。

为什么不在MultiArray 中定义operator+=?这样,它将为定义了operator+= 的每个T 定义。如果您想要特定的行为,您可以使用静态辅助类函数,您可以在其中针对每种数据类型专门化操作符的行为。

【讨论】:

  • 其实我并没有选择模板规范以避免重复......而且我认为我不需要任何带有T = double的辅助类函数。
  • 那么,我的第二个解决方案(最后一段)呢?我认为这将符合您的目的。您只需在MultiArray 中定义operator+=,并使用默认实现。但是,如果您想要一个 T 的特定行为,您必须让 operator+= 调用一个辅助结构,您可以指定它具有所需的行为。
  • 是的,它可以工作,但如果我想拥有一个具有特定功能的类 MultiArrayDouble,那就不太令人满意了。
  • 让操作员处理任何MultiArray&lt;double, N&gt; 而不是MultiArrayDouble 怎么样?
猜你喜欢
  • 2021-05-16
  • 1970-01-01
  • 2018-05-23
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多