1

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?

Julian Aßmann
  • 190
  • 1
  • 13
  • Does this answer your question? ["invalid use of incomplete type" error with partial template specialization](https://stackoverflow.com/questions/165101/invalid-use-of-incomplete-type-error-with-partial-template-specialization) – Quimby Dec 13 '20 at 11:40

1 Answers1

1

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";
        }
    }
};
d_kog
  • 143
  • 6
  • Thank you very much, this works perfectly. Do you know if there is any way to achieve this with only C++11 features. – Julian Aßmann Dec 17 '20 at 09:20
  • 1
    @Julian Aßmann I see at least three solutions, first one to use partial specialization and have two versions of your class, second you can use 'Tag Dispatching' (pass bool to underlying function with implementation), and third nearest to 'if constexpr' is to use std::enable_if. I wrote example for third approach: https://godbolt.org/z/Mbsnxz – d_kog Dec 17 '20 at 23:13