vs10编译器这是一个bug吗?

时间:2012-09-29 16:22:10

标签: c++ visual-studio-2010 compiler-construction

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次错误,但项目可以成功构建并运行:

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中调用项目重建并成功运行,没有错误。 所以发生了什么事?它困惑了我......

1 个答案:

答案 0 :(得分:0)

在评论第158行之后实际上没有错误,但是C ++ intellisense仍然会想到你的旧代码或可能在解析你的代码时出错,MSVC团队认为这是他们的intellisense引擎中的一个错误,但是他们说他们不能修复它直到MSVC2012,所以如果你可以请用那个版本测试你的代码