smlq smlq - 3 months ago 6
C++ Question

How to conditionally add a function to a class template?

I have a Matrix class template as follows:

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


What I want is to define a
.setIdentity()
function only for instantiations when
nrows==ncols
is
true
at compile time. And there will be no definition of
.setIdentity()
when
nrows==ncols
is
false
.

What I am trying is using
enable_if
idiom, but that will define the function for all cases. Isn't it?

Answer

You can do it with std::enable_if in the following mode

template <std::size_t r = nrows, std::size_t c = ncols>
typename std::enable_if<r == c>::type setIdentity ()
 { /* do something */ }

A full example

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