Mat2D.h
#pragma once
#include <iostream>
#include <iomanip>
#include <assert.h>
namespace Ggicci
{
template<class T>
class Mat2D
{
private:
int _rows;
int _cols;
T** _data;
public:
Mat2D()
:_rows(0), _cols(0), _data(NULL)
{
}
Mat2D(const Mat2D<T>& rhs)
:_rows(rhs._rows), _cols(rhs._cols)
{
allocateData();
cloneData(rhs._data);
}
Mat2D(int rows, int cols)
{
initSize(rows, cols);
allocateData();
all(0);
}
Mat2D(int rows, int cols, T initValue)
{
initSize(rows, cols);
allocateData();
all(initValue);
}
Mat2D(int rows, int cols, const T* data)
{
initSize(rows, cols);
allocateData();
assignData(data);
}
~Mat2D()
{
destroyData();
}
const Mat2D& operator = (const Mat2D<T>& rhs)
{
if (this == &rhs)
{
return *this;
}
this->resize(rhs._rows, rhs._cols);
this->cloneData(rhs._data);
return *this;
}
T& operator() (int row, int col)
{
assert(row >= 0 && row < _rows && col >= 0 && col < _cols);
return _data[row][col];
}
T operator() (int row, int col) const
{
assert(row >= 0 && row < _rows && col >= 0 && col < _cols);
return _data[row][col];
}
Mat2D<T> operator * (const Mat2D<T>& rhs)
{
assert(this->_cols == rhs._rows);
int new_rows = this->_rows;
int new_cols = rhs._cols;
Mat2D<T> result(new_rows, new_cols);
for (int i = 0; i < new_rows; i++)
{
for (int j = 0; j < new_cols; j++)
{
T sum = 0;
for (int k = 0; k < this->_cols; k++)
{
sum += this->_data[i][k] * rhs._data[k][j];
}
result._data[i][j] = sum;
}
}
return result;
}
void resize(int rows, int cols)
{
destroyData();
initSize(rows, cols);
allocateData();
all(0);
}
void all(T value)
{
for (int i = 0; i < _rows; i++)
for (int j = 0; j < _cols; j++)
_data[i][j] = value;
}
private:
void initSize(int rows, int cols)
{
assert(rows > 0 && cols > 0 && rows < 65536 && cols < 65536);
_rows = rows;
_cols = cols;
}
void allocateData()
{
_data = new T*[_rows];
for(int i = 0; i < _rows; i++)
{
_data[i] = new T[_cols];
}
}
void assignData(const T* data)
{
for (int i = 0; i < _rows; i++)
{
for (int j = 0; j < _cols; j++)
{
_data[i][j] = data[i*_rows + j];
}
}
}
void cloneData(T** data)
{
for (int i = 0; i < _rows; i++)
for (int j = 0; j < _cols; j++)
_data[i][j] = data[i][j];
}
void destroyData()
{
for(int i = 0; i < _rows; i++)
delete _data[i];
delete _data;
}
/*template<class T>*/ //--> Line 158
friend std::ostream& operator << (std::ostream& out, const Mat2D<T>& rhs)
{
for(int i = 0; i < rhs._rows; i++)
{
for(int j = 0; j < rhs._cols; j++)
{
out << std::setw(12) << rhs._data[i][j];
}
out << std::endl;
}
return out;
}
};
}
main.cpp
#include <iostream>
#include <string>
#include <cmath>
#include "Mat2D.h"
using namespace std;
using namespace Ggicci;
Mat2D<float> getRotateMatrix33f(float theta, const Mat2D<float>& ref_point = Mat2D<float>(1, 2, 0.0f))
{
theta = theta / 180 * 3.1415f;
float rotate[] = {
cos(theta), -sin(theta), 0,
sin(theta), cos(theta), 0,
0, 0, 1
};
Mat2D<float> result(3, 3, rotate);
if (ref_point(0, 0) != 0 && ref_point(0, 1) != 0)
{
float dx = ref_point(0, 0);
float dy = ref_point(0, 1);
float translate_data[] = {
1, 0, 0,
0, 1, 0,
dx, dy, 1
};
float translate_inv_data[] = {
1, 0, 0,
0, 1, 0,
-dx, -dy, 1
};
Mat2D<float> translate(3, 3, translate_data);
Mat2D<float> translate_inv(3, 3, translate_inv_data);
result = translate * result * translate_inv;
}
return result;
}
int main()
{
int data_a[] = {1, 2};
int data_b[] = {2, 3, 4, 5, 6, 7, 8, 9};
Mat2D<int> a(1, 2, data_a);
Mat2D<int> b(2, 4, data_b);
Mat2D<int> c;
c = a * b;
cout << "c = " << endl << c << endl;
cout << "rotate matrix: " << endl << getRotateMatrix33f(30.0f) << endl;
return 0;
}
If I comment line 158
in Mat2D.h
, every thing is okay, the project can build and run successfully though 4 errors occur:
If I don't comment line 158
,
error C2995: 'std::ostream &Ggicci::operator <<(std::ostream &,const Ggicci::Mat2D<T>
&)' : function template has already been defined.
Then I comment the function getRotateMatrix33f
and its invoking in main
the project rebuild and run successfully with no errors.
So what happened? It confused me...
There is actually no error after commenting line 158, but C++ intellisense still think of your old code or probably mistake in parsing your code, MSVC team accepted this to be a bug in their intellisense engine but they said that they can't fix it untill MSVC2012, so if you can please test your code with that version