我有一个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
,但我不确定如何继续进行。
答案 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
,只有在行和列不相同且行数匹配时才会处于活动状态。