我有一个Matrix类模板,如下所示:
template<typename T, std::size_t nrows, std::size_t ncols>
class Matrix
{
T data[nrows][ncols];
public:
T& operator ()(std::size_t i, std::size_t j)
{
return data[i][j];
}
};
我想要的是仅在编译时
.setIdentity()
是nrows==ncols
时为实例化定义true
函数。当.setIdentity()
为nrows==ncols
时,将没有false
的定义。我正在尝试使用
enable_if
惯用法,但这将定义所有情况下的功能。是不是 最佳答案
您可以在以下模式下使用std::enable_if
进行操作
template <std::size_t r = nrows, std::size_t c = ncols>
typename std::enable_if<r == c>::type setIdentity ()
{ /* do something */ }
一个完整的例子
#include <type_traits>
template<typename T, std::size_t nrows, std::size_t ncols>
class Matrix
{
T data[nrows][ncols];
public:
T& operator ()(std::size_t i, std::size_t j)
{ return data[i][j]; }
template <std::size_t r = nrows, std::size_t c = ncols>
typename std::enable_if<r == c>::type setIdentity ()
{ /* do something */ }
};
int main()
{
Matrix<int, 3, 3> mi3;
Matrix<int, 3, 2> mnoi;
mi3.setIdentity();
// mnoi.setIdentity(); error
return 0;
}
---编辑---
正如Niall在评论中所指出的(关于TemplateRex的答案,但我的解决方案也存在相同的缺陷),可以通过这种方式来回避此解决方案,以明确显示行数和列数
mi3.setIdentity<4, 4>();
(但这不是一个真正的问题(IMHO),因为
mi3
是一个方矩阵,并且setIdentity()
可以使用实际尺寸(nrows
和ncols
)),甚至可以使用mnoi.setIdentity<4, 4>()
(这是一个大问题(恕我直言),因为
mnoi
不是方形矩阵)。显然有Niall提出的解决方案(添加
static_assert
;类似 template <std::size_t r = nrows, std::size_t c = ncols>
typename std::enable_if<r == c>::type setIdentity ()
{
static_assert(r == nrows && c == ncols, "no square matrix");
/* do something else */
}
或类似的内容),但我建议在
std::enable_if
中添加相同的检查。我是说
template <std::size_t r = nrows, std::size_t c = ncols>
typename std::enable_if< (r == c)
&& (r == nrows)
&& (c == ncols)>::type setIdentity ()
{ /* do something */ }