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;
}
如果我在line 158
中评论Mat2D.h
,那么每件事都没问题,虽然发生了4次错误,但项目可以成功构建并运行:
如果我不评论line 158
,
error C2995: 'std::ostream &Ggicci::operator <<(std::ostream &,const Ggicci::Mat2D<T>
&)' : function template has already been defined.
然后我评论函数getRotateMatrix33f
及其在main
中调用项目重建并成功运行,没有错误。
所以发生了什么事?它困惑了我......
答案 0 :(得分:0)
在评论第158行之后实际上没有错误,但是C ++ intellisense仍然会想到你的旧代码或可能在解析你的代码时出错,MSVC团队认为这是他们的intellisense引擎中的一个错误,但是他们说他们不能修复它直到MSVC2012,所以如果你可以请用那个版本测试你的代码