I want to compose a Matrix class template.
Matrix objects need to copy data very often, such as in copy constructor or assignment operator overload function, so it need to be efficient.
For most cases, I should not escape the assignment operator overload function of each data item, but for simple data types, I prefer using memcpy() to speed it up.

So I write like this:

#ifndef GRAPHIC_VECTOR_H
#define GRAPHIC_VECTOR_H

namespace Graphic
{
	template <typename T>
	class Matrix
	{
	private:
		unsigned row, col;
		T* data;
		void CopyData(T* dest, T* src, unsigned count);
	public:
		Matrix(unsigned row, unsigned col, T* data, int count = -1) : row(row), col(col)
		{
			this->data = new T[row * col];
			CopyData(this->data, data, (count > 0 ? count : row * col * sizeof(T)));
		}
		~Matrix()
		{
			delete[] this->data;
		}
	};
	
	template <typename T>
	void Matrix<T>::CopyData(T* dest, T* src, unsigned count)
	{
		int i;
		for (i = 0; i < count; i++)
		{
			dest[i] = src[i];
		}
	}
	
	template <>
	void Matrix<double>::CopyData(double* dest, double* src, unsigned count)
	{
		memcpy(dest, src, count);
	}
	
	template <>
	void Matrix<float>::CopyData(float* dest, float* src, unsigned count)
	{
		memcpy(dest, src, count);
	}
	
	template <>
	void Matrix<int>::CopyData(int* dest, int* src, unsigned count)
	{
		memcpy(dest, src, count);
	}
	
	template <>
	void Matrix<unsigned>::CopyData(unsigned* dest, unsigned* src, unsigned count)
	{
		memcpy(dest, src, count);
	}
}

#endif

Then I do this in the main function:

double data[9] = {1,2,3,4,5,6,7,8,9};
	Graphic::Matrix<double> m(3,3,data);

Compilation is a great success but I got some link errors:

Linking...
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\controller.o(.text+0x0): In function `ZN7Graphic6MatrixIdE8CopyDataEPdS2_j':
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:37: multiple definition of `Graphic::Matrix<double>::CopyData(double*, double*, unsigned)'
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\winmain.o(.text+0x0):C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\winmain.cpp: first defined here
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\controller.o(.text+0x22): In function `ZN7Graphic6MatrixIfE8CopyDataEPfS2_j':
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:43: multiple definition of `Graphic::Matrix<float>::CopyData(float*, float*, unsigned)'
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\winmain.o(.text+0x22):C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:43: first defined here
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\controller.o(.text+0x44): In function `ZN7Graphic6MatrixIiE8CopyDataEPiS2_j':
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:49: multiple definition of `Graphic::Matrix<int>::CopyData(int*, int*, unsigned)'
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\winmain.o(.text+0x44):C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:49: first defined here
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\controller.o(.text+0x66): In function `ZN7Graphic6MatrixIjE8CopyDataEPjS2_j':
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:55: multiple definition of `Graphic::Matrix<unsigned>::CopyData(unsigned*, unsigned*, unsigned)'
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\winmain.o(.text+0x66):C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:55: first defined here
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\graphic.o(.text+0x0): In function `ZN7Graphic6MatrixIdE8CopyDataEPdS2_j':
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:37: multiple definition of `Graphic::Matrix<double>::CopyData(double*, double*, unsigned)'
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\winmain.o(.text+0x0):C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\winmain.cpp: first defined here
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\graphic.o(.text+0x22): In function `ZN7Graphic6MatrixIfE8CopyDataEPfS2_j':
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:43: multiple definition of `Graphic::Matrix<float>::CopyData(float*, float*, unsigned)'
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\winmain.o(.text+0x22):C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:43: first defined here
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\graphic.o(.text+0x44): In function `ZN7Graphic6MatrixIiE8CopyDataEPiS2_j':
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:49: multiple definition of `Graphic::Matrix<int>::CopyData(int*, int*, unsigned)'
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\winmain.o(.text+0x44):C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:49: first defined here
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\graphic.o(.text+0x66): In function `ZN7Graphic6MatrixIjE8CopyDataEPjS2_j':
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:55: multiple definition of `Graphic::Matrix<unsigned>::CopyData(unsigned*, unsigned*, unsigned)'
C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\Debug\winmain.o(.text+0x66):C:\Users\deltamaster\Documents\MinGWProject\graphic\3d\graphic\matrix.h:55: first defined here

Member Avatar for embooglement

I copy and pasted this into Visual Studio 2010 Express Edition and it works fine. I'm thinking that your compiler just doesn't have good support for templates. What compiler and version are you using?

I copy and pasted this into Visual Studio 2010 Express Edition and it works fine. I'm thinking that your compiler just doesn't have good support for templates. What compiler and version are you using?

I'm using MinGW, gcc version 3.3.1

Member Avatar for embooglement

I don't know a whole lot about that compiler, I'd suggest googling for a bit and seeing if it has issues with templates. But like I said, this compiles on Visual Studio, and I can't see anything wrong with the code at all, so it's most definitely the compile that's the issue. Is that the most up to date version of it?

Add the keyword "inline" in front of ALL function implementations, as so:

template <>
inline void Matrix<double>::CopyData(double* dest, double* src, unsigned count)

That should fix your problem.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.