如何有条件地向类模板添加函数?

用户名

我有一个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==ncolstrue在编译的时候。而且when is没有定义.setIdentity()nrows==ncolsfalse

我正在尝试使用enable_if成语,但这将定义所有情况下的功能。是不是

最高66

您可以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()可以使用实际尺寸(nrowsncols)),甚至

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 */ }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章