Search code examples
c++templatestemplate-specializationspecialization

Partial specialisation of member function with non-type parameter of a class with non-type parameter


I have a matrix class with a toString() method:

template <typename T, int rowCount, int columnCount>
class Matrix
{
//...
public:
    std::string toString() const
    {
        // ...
    }
};

Now I want to specialize toString() for the case, that T is Matrix so that it returns a string in a different format in the case of

Matrix<Matrix<double, 2, 2>, 3, 3> a;
std::string s = a.toString();

to say this case:

Matrix<double, 2, 2> a;
std::string s = a.toString();

I tried something like this

template <int rows, int cols>
template <typename X, int rows_inside, int cols_inside>
std::string Matrix<Matrix<X, rows_inside, cols_inside>, rows, cols>::toString() const
{
    //...
}

but it does not work.

How can I achieve this effect?


Solution

  • You can use if constexpr to achieve this.

    template <typename, int, int>
    class Matrix;
    
    template <typename>
    struct IsMatrix : std::false_type
    {
    };
    
    template <typename T, int N, int M>
    struct IsMatrix<Matrix<T, N, M>> : std::true_type
    {
    };
    
    template <typename T, int rowCount, int columnCount>
    class Matrix
    {
        //...
    public:
        std::string toString() const
        {
            if constexpr (IsMatrix<T>::value)
            {
                return "matrix";
            }
            else
            {
                return "not matrix";
            }
        }
    };