2012-09-29 61 views
0

Mat2D.h
vs10編譯器是這個bug嗎?

#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 158Mat2D.h,每一件事情是好的,項目可以建立併成功運行雖然出現4個錯誤:

image of code snippet image of error info output

如果我不評論line 158

error C2995: 'std::ostream &Ggicci::operator <<(std::ostream &,const Ggicci::Mat2D<T> 
&)' : function template has already been defined. 

然後我評論的功能getRotateMatrix33f及其main調用項目重建並沒有任何錯誤成功運行。 那麼發生了什麼?它讓我困惑......

+0

你真的編譯?這不是一個編譯器錯誤,這是智能感知,並且毫無意義。 –

+0

@LuchianGrigore VS2010 Intellisense在實際編譯之前使用預編譯捕獲編譯器錯誤,以加快開發速度。如果Ggicci要編譯代碼,那麼*會是一個編譯器錯誤。 – Casey

+0

@LuchianGrigore對不起,但你能告訴我編譯器錯誤和intellisense之間的區別,我不明白爲什麼vs10現在代碼可以正常工作強調了朋友函數中的私有變量。 – Ggicci

回答

0

在評論第158行後實際上沒有錯誤,但C++ intellisense仍然會想到你的舊代碼或可能在解析你的代碼時出錯,MSVC團隊接受這是他們的intellisense引擎中的一個錯誤,但他們說他們無法修復它,直到MSVC2012,所以如果你可以請測試你的代碼與該版本