(注意:在没有C ++ 0x标志和外部限制的GCC 4.6上工作。我也对C ++ 11和/或更新的编译器会发生什么感兴趣)
我有一个用于在固定大小的矩阵上进行操作的模板化类:
template<size_t rows, size_t cols, class Type>
class MatrixFixed;
在该类中,我定义了一个具有以下方面的“移位”操作:
template<size_t rows, size_t cols, class Type>
template<size_t numRowsUp>
MatrixLogicalFixed<rows,cols,Type> MatrixLogicalFixed<rows,cols,Type>::shiftUp( const Type & filler ) const
{
if( (numRowsUp>=rows) )
{
return MatrixLogicalFixed<rows,cols,Type>(filler);
}
else
{
MatrixLogicalFixed<numRowsUp,cols,Type> temp(filler);
return this->getSubMatrix<rows-numRowsUp,cols>( numRowsUp, 0 )
.joinV( temp );
}
}
这个想法是,如果要移动的位置数大于总行数,则可以返回一个填充有默认值的矩阵。
但是,在这些情况下(
numRowsUp >= rows
),编译会以内部编译器错误结束:在最后一条代码行.joinV( temp )
上gimplify.c:691的force_constant_size中在此过程中的矩阵大小(我猜):
返回值:(行x列)矩阵
getSubMatrix<rows-numRowsUp,cols>( numRowsUp, 0 )
:当numRowsUp>=rows
时,由于size_t下溢,将导致数量巨大joinV
函数尝试推断出适当的返回大小,但这是不可能的。这是joinV声明):
template<size_t rows, size_t cols, class Type>
template<size_t rows2, size_t cols2>
MatrixLogicalFixed<rows+rows2,cols,Type> MatrixLogicalFixed<rows,cols,Type>::joinV(const MatrixLogicalFixed<rows2,cols2,Type> & B) const
由于
if
条件是在编译时定义的,因此在有问题的情况下,这是永远不会达到的代码。到目前为止我尝试过的是:在预处理器#if中使用模板参数-显然是错误的。
寻找可以解决问题的任何预处理程序宏MIN或MAX。
通常的部分专业化似乎不是有效的解决方法,因为存在无限的值组合...我愿意接受任何一种解决方案。我只希望我的班级编译:D
最佳答案
预处理器MAX有什么问题?
您可以使用MAX(0, rows-numRowsUp)
作为模板参数。或尝试将其作为模板参数:(numRowsUp>=rows)? 0 : rows-numRowsUp
。这样永远不会实例化错误的模板。