0

I recently learned about c++ templates and was testing them out with a matrix class:

template<typename T>

class Matrix
{
    public:
        Matrix();

        int width;
        int height;

        Matrix operator*(const Matrix& rMatrix)
        Matrix operaor+(const Matrix& rMatrix)

        // other matrix operations/functions here
    private:
        T* data;
};

I then found that templates could take non-type parameters, allowing me to do this:

template<typename T, int width, int height>

class Matrix
{
    public:
        Matrix();

        template <int width2>
        Matrix<T, width2, height> operator*(const Matrix<width2, width>7 rMatrix)

        // other matrix operations/functions here

    private:
        T* data;
};

I figured that the latter was probably better if you knew all the sizes you would need at compile-time, as it would generate compilation errors if the matrices were the wrong size (for the multiplication/addition operations), whereas the former forced me to check this at run-time. I was, however, worried that the compiler would be generating different functions for adding a 4x4 to a 4x4 vs a 3x3 to a 3x3 (assuming both had the same type), which would be inefficient.

So my question is this: will the compiler I'm using (g++) generate multiple functions from a template when there is a variation in a non-type parameter (in the above example, matrix width/height)?

edit/clarifications:

  • the functions are not defined inline (they are in a separate .tpp file)
  • by 'inefficient', I mean that (by my understanding) having these variations on the function will cause the compiled executable to be larger than it would otherwise be
4
  • It may depend on whether the functions are defined inline. Commented Jun 6, 2019 at 2:54
  • Also, why do you think it would be inefficient to define multiple functions like that? (it usually isn't) Commented Jun 6, 2019 at 2:54
  • Compile it and see what happens. Commented Jun 6, 2019 at 3:26
  • You might still forward your template functions to regular function to avoid/minimize bloating code. Commented Jun 6, 2019 at 9:16

1 Answer 1

0

Take a look at C++ Insights.

If you paste your code there and add a main function that uses two matrix types with different height and widths (see here and click on the "play" button), you can observe what the compiler generates:

template<typename T, int width, int height>
class Matrix
{
public:
    Matrix();

    template <int width2>
    Matrix<T, width2, height> operator*(const Matrix<T, width2, width> rMatrix);

    // other matrix operations/functions here

private:
    T* data;
};

/* First instantiated from: insights.cpp:18 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class Matrix<double, 1, 2>
{

public: 
  Matrix();

  template<int width2>
  Matrix<double, width2, 2> operator*(const Matrix<double, width2, 1> rMatrix);

private: 
  double * data;
public: 
  // inline constexpr Matrix(const Matrix<double, 1, 2> &) = default;
  // inline constexpr Matrix(Matrix<double, 1, 2> &&) = default;
};

#endif


/* First instantiated from: insights.cpp:19 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class Matrix<double, 2, 1>
{

public: 
  Matrix();

  template<int width2>
  Matrix<double, width2, 1> operator*(const Matrix<double, width2, 2> rMatrix);

private: 
  double * data;
public: 
  // inline constexpr Matrix(const Matrix<double, 2, 1> &) = default;
  // inline constexpr Matrix(Matrix<double, 2, 1> &&) = default;
};

#endif


int main()
{
  Matrix<double, 1, 2> Matrix1 = Matrix<double, 1, 2>();
  Matrix<double, 2, 1> Matrix2 = Matrix<double, 2, 1>();
}

Therefore, yes, versions for all the combinations of width and height used somewhere else in the code are generated.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.