不同非类型模板参数的不同成员函数

时间:2017-06-12 15:05:45

标签: c++ templates operator-overloading overloading

我有一个Vector班级和一个Matrix班级。我想使用Vector运算符隐式地将Matrix类转换为=类。类的定义如下所示。

template <unsigned int dim>
class Vector {
public:
  std::array<double, dim> x;
};

template <unsigned int nrow, unsigned int ncol>
class Matrix {
public:
  std::array<Vector<ncol>, nrow> x;

  auto& operator=(Vector<ncol> v)
  {
    x.fill(v);
    return *this;
  }
};

int main()
{
  Vector<2> vec1;
  vec1.x[0] = 1;
  vec1.x[1] = 2;

  Matrix<1, 2> mat1;
  mat1 = vec1;

  std::cout << mat1.x[0].x[0] << std::endl;
  std::cout << mat1.x[0].x[1] << std::endl;
}

这是正常的。但是,我想介绍另一个operator=,它应该如下所示。

auto& operator=(Vector<nrow> v)
{
  for(unsigned int row=0; row < nrow; ++row){
    x[row].x[0] = v[row];
  }
  return *this;
}

但是,由于重载实例化为相同的签名(对于nrow=ncol的情况),我不确定如何设计这样的方法。具体来说,我想知道是否可以仅在nrow!=ncol时定义第二种方法。

我尝试通过定义两种类型

来使用std::enable_if
using nrow_t = std::integral_constant<unsigned int,nrow>;
using ncol_t = std::integral_constant<unsigned int,ncol>;

然后使用std::is_same,但我不确定如何继续进行。

1 个答案:

答案 0 :(得分:2)

这可能是使用命名函数会更容易的情况。它将准确地传达正在发生的事情并且不会让任何人惊讶。那说你可以使用这样的东西

template <unsigned int nrow, unsigned int ncol>
class Matrix {
public:
    std::array<Vector<ncol>, nrow> x;

    template<unsigned int cols,
             std::enable_if_t<cols == ncol || (cols == ncol && ncol == nrow)>* = nullptr>
    auto& operator=(Vector<cols> v)
    {
        x.fill(v);
        return *this;
    }
    template<unsigned int rows,
             std::enable_if_t<rows == nrow && nrow != ncol>* = nullptr>
    auto& operator=(Vector<rows> v)
    {
        for(unsigned int row=0; row < nrow; ++row){
            x[row].x[0] = v[row];
        }
        return *this;
    }
};

对于enable_if为真时的第一次重载cols == ncol || (cols == ncol && ncol == nrow)。当它具有正确的数量时,如果列或行和列相同且具有正确的列数,则会发生这种情况。第二个重载使用rows == nrow && nrow != ncol,只有在行和列不相同且行数匹配时才会处于活动状态。

相关问题