【问题标题】:Different member function for Different Non-Type Template Parameters不同非类型模板参数的不同成员函数
【发布时间】:2017-06-12 15:05:44
【问题描述】:

我有一个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,但我不确定如何继续。

【问题讨论】:

  • enable_if 看起来是解决问题的直接方法。你已经尝试过什么?
  • 我会重新考虑使用operator= 来执行此操作的决定,以避免给不知情的程序员带来意外。尤其是当行为取决于天气nrow == ncol 与否时。
  • 我强烈建议使用更有意义的函数名而不是钝的句法技巧。 fillByRowfillByColumnsetRowsetColumnoperator= 的重载含义更容易理解,具体取决于 nrowncol 的值 Matrixnrow Vector.
  • 想了想,同意@alain。

标签: c++ templates operator-overloading overloading


【解决方案1】:

这可能是使用命名函数会容易得多的情况。它将准确地传达正在发生的事情,不会让任何人感到惊讶。也就是说你可以使用这样的东西

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;
    }
};

cols == ncol || (cols == ncol &amp;&amp; ncol == nrow) 为真时,我们enable_if 第一次重载。当它具有正确的数量时会发生这种情况,因为列或行和列相同并且它具有正确的列数量。第二个重载使用rows == nrow &amp;&amp; nrow != ncol,并且仅在行和列不相同且行数匹配时才会激活。

【讨论】:

  • 我同意您的建议,仍然感谢您的解决方案。
  • @JayeshBadwaik 没问题。很高兴为您提供帮助。
  • 这是 C++11 和 C++14 的有趣组合。如果你使用 C++14 特性,你可以避免使用typename std::enable_if&lt;&gt;::type,而使用std::enable_if_t&lt;&gt;
  • @Walter 你是对的。我只是习惯了name&lt;&gt;::type,我忘了还有name_t&lt;&gt; 类型。我会更新,因为这显然是 C++14。
  • @DanielJour 由于 C++14 是当前标准,我们应该使用它,除非 OP 另有要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-09
  • 1970-01-01
  • 1970-01-01
  • 2018-12-16
  • 2020-04-13
  • 1970-01-01
相关资源
最近更新 更多