簡體   English   中英

Matrix模板類通過const引用傳遞參數

[英]Matrix Template Class passing parameter by const reference

試圖為矩陣對象編寫模板類。 編譯錯誤:

c:\\ program files(x86)\\ microsoft visual studio 11.0 \\ _vc \\ include \\ xmemory0(606):錯誤C2558:類'Matrix':沒有可用的復制構造函數或復制構造函數被聲明為'explicit'1> with 1> [1 > T = float 1>] 1> c:\\ program files(x86)\\ microsoft visual studio 11.0 \\ vc \\ include \\ xmemory0(605):同時編譯類模板成員函數'void std :: allocator <_Ty> :: construct (_Ty *,const _Ty&)'1>
1> [1> _Ty = Matrix 1>] 1> c:\\ program files(x86)\\ microsoft visual studio 11.0 \\ vc \\ include \\ xmemory0(751):參見函數模板實例化'void std :: allocator < _Ty> :: construct(_Ty *,const _Ty&)'正在編譯1> 1> [1>
_Ty = Matrix 1>] 1> c:\\ program files(x86)\\ microsoft visual studio 11.0 \\ vc \\ include \\ type_traits(743):參見類模板實例化'std :: allocator <_Ty>'正在編譯1>用1> [1>
_Ty = Matrix 1>] 1> c:\\ program files(x86)\\ microsoft visual studio 11.0 \\ vc \\ include \\ vector(655):參見類模板實例化'std :: is_empty <_Ty>'正在編譯1>用1> [1>
_Ty = std :: allocator> 1>] 1> e:\\ projects \\ work \\ nns \\ fifteenstepstut \\ fifteensteps \\ fifteensteps \\ source.cpp(35):請參閱類模板實例化'std :: vector <_Ty>'的引用編譯1> 1> [1>
_Ty = Matrix 1>] 1> 1>構建失敗。 1>

ClCompile:1> Source.cpp 1> e:\\ projects \\ work \\ nns \\ fifteenstepstut \\ fifteensteps \\ fifteensteps \\ matrix.h(80):error C2664:'Matrix :: Matrix(Matrix&)':無法轉換參數1 'Matrix(__ cdecl *)(void)'到'Matrix&'1>
1> [1> T = float 1>] 1>
e:\\ projects \\ work \\ nns \\ fifteenstepstut \\ fifteensteps \\ fifteensteps \\ matrix.h(74):編譯類模板成員函數'Matrix Matrix :: dot(const Matrix&)'1> with 1> [1>
T = float 1>] 1>
e:\\ projects \\ work \\ nns \\ fifteenstepstut \\ fifteensteps \\ fifteensteps \\ source.cpp(62):參見函數模板實例化'Matrix Matrix :: dot(const Matrix&)'正在編譯1> 1> [1> T = float 1>] 1>
e:\\ projects \\ work \\ nns \\ fifteenstepstut \\ fifteensteps \\ fifteensteps \\ source.cpp(38):參見類模板實例化'Matrix'正在編譯1> 1> [1> T = float 1>
] 1> e:\\ projects \\ work \\ nns \\ fifteenstepstut \\ fifteensteps \\ fifteensteps \\ matrix.h(84):錯誤C2664:'Matrix :: Matrix(Matrix&)':無法從'Matrix(__cdecl *)轉換參數1 (void)'to'Matrix&'1>
1> [1> T = float 1>] 1> 1> Build FAILED。

“Matrix.h”

#include <vector>
#include <iostream>

template<typename T>
class Matrix {
private: 
    std::vector<T> data;
    int rows;
    int cols;

public:
    Matrix();
    Matrix(std::vector<T>, int rows, int cols);
    Matrix(Matrix<T>&); //change with this one
    //Matrix(const Matrix<T>&); //Will need to uncomment to test the 3rd error
    void print();
    Matrix<T> transpose();
    Matrix<T> dot(const Matrix<typename std::remove_reference<T>::type> &); //error 2
    //Matrix<T&> dot(const Matrix<T> &); //dumb idea?
    //Matrix<T> dot(const Matrix<T> &); //error 1
};

template <typename T>
Matrix<T>::Matrix() {
    data.clear();
    rows = 0;
    cols = 0;
}

template <typename T> 
Matrix<T>::Matrix(std::vector<T> elements, int numRows, int numCols) {
    rows = numRows;
    cols = numCols;

    data.clear();
    for(unsigned int i = 0; i < elements.size(); i++) {
        data.push_back(elements[i]);
    }
}

template <typename T> 
Matrix<T>::Matrix(Matrix<T>& matrix) {
    rows = matrix.rows;
    cols = matrix.cols;

    data.clear();
    for(unsigned int i = 0; i < matrix.data.size(); i++) {
        data.push_back(matrix.data[i]);
    }
}
/* To get compiler error, exchange with a above
template <typename T> 
Matrix<T>::Matrix(const Matrix<T>& matrix) {
    rows = matrix.rows;
    cols = matrix.cols;

    data.clear();
    for(unsigned int i = 0; i < matrix.data.size(); i++) {
        data.push_back(matrix.data[i]);
    }
}*/

template <typename T>
Matrix<T> Matrix<T>::dot(const Matrix<typename std::remove_reference<T>::type> & rhs) { //ERROR 2
//Matrix<&T> dot(const Matrix<T> &) {   
//Matrix<T> dot(const Matrix<T> &) { ERROR 1
    if(cols != rhs.rows) {
        std::cout << "Error! Can not resolve dot product on these matrices!" << std::endl;
        std::cout << "Requested: [" << rows << "x" << cols << "] <alt+7> [" << rhs.rows << "x" << rhs.cols << "]" << std::endl;
        Matrix<T> matrix();
        return matrix;
    }

    Matrix<T> matrix();
    return matrix;
}

template <typename T>
void Matrix<T>::print() {
    for(unsigned int i = 0; i < data.size(); i++) {
        std::cout << data[i] << ", ";
        if((i+1) % cols == 0)
            std::cout << std::endl;
    }
}

template <typename T>
Matrix<T> Matrix<T>::transpose() {
    std::vector<T> vec;
    for(unsigned int i = 0; i < data.size(); i++) {
        vec.push_back(data[(cols*(i%rows)+i/rows)]);
    }
    return Matrix<T>(vec, cols, rows);
}

我已經閱讀了幾個關於如何糾正這個問題的不同想法,但不確定問題是什么。 很多地方都在談論將T作為const引用傳遞,但在這種情況下,我將該類作為const引用傳遞。 似乎不喜歡那樣。

我終於決定看看如果實現一個const引用復制構造函數會發生什么。

然后我得到這個錯誤:

未解決的外部符號“public:class Matrix __thiscall Matrix :: dot(class Matrix const&)”(?dot @?$ Matrix @ M @@ QAE?AV1 @ ABV1 @@ Z)在函數“void __cdecl testMatrixClass(void)”中引用“(?testMatrixClass @@ YAXXZ)

如果可能的話,我怎么能完成將這個類作為const引用傳遞?

謝謝!

測試實施

SOURCE.CPP

#include <iostream>
#include <vector>
#include "Matrix.h"
#include <string>
#include <fstream>
#include <sstream>


////TODO: Find alternatives to these...
//typedef std::vector<std::vector<float>> Matrix;
//typedef std::vector<float> Vector;
//using LMath::operator+;
//using LMath::operator==;



//void testMatrix(); //testing function.
//Matrix loadData(std::string); //Not implemented yet
//bool saveData(Matrix, std::string); //Not implemented yet


void testMatrixClass();

int main() {

    //testMatrix();
    testMatrixClass();

    return 0;
}


void testMatrixClass() {

    std::vector<Matrix<float>> testResults;
    std::vector<std::string> testInfo;

    Matrix<float> temp;
    testResults.push_back(temp);
    testInfo.push_back("Default Constructor");

    std::vector<float> tempVec;
    for(int i = 0; i < 9; i++) {
        tempVec.push_back((float)(i%3));
    }

    Matrix<float> temp2(tempVec, 3, 3);
    testResults.push_back(temp2);
    testInfo.push_back("Vector constructor");

    testResults.push_back(temp2.transpose());
    testInfo.push_back("Vector transpose");

    tempVec.push_back(10.0);
    Matrix<float> temp3(tempVec, 5, 2);
    testResults.push_back(temp3);
    testInfo.push_back("Vector constructor");

    testResults.push_back(temp3.transpose());
    testInfo.push_back("Vector transpose");

    testResults.push_back(temp2.dot(temp2));
    testInfo.push_back("Dot product");

    testResults.push_back(temp2.dot(temp3));
    testInfo.push_back("Error Dot Product");

    for(unsigned int i = 0; i < testResults.size(); i++) {
        std::cout << "Test: " << testInfo[i] << ": " << std::endl;;
        testResults[i].print();
        std::cout << std::endl;
    }

}

解:

#include <iostream>
#include <vector>
template<typename T>
class Matrix {
private: 
    std::vector<T> data;
    int rows;
    int cols;

public:
    Matrix();
    Matrix(std::vector<T>, int rows, int cols);
    //Matrix(Matrix<T>&);
    Matrix(const Matrix<T>&);
    void print();
    Matrix<T> transpose();
    Matrix<T> dot(const Matrix<typename std::remove_reference<T>::type> &);
};

template <typename T>
Matrix<T>::Matrix() {
    data.clear();
    rows = 0;
    cols = 0;
}

template <typename T> 
Matrix<T>::Matrix(std::vector<T> elements, int numRows, int numCols) {
    rows = numRows;
    cols = numCols;

    data.clear();
    for(unsigned int i = 0; i < elements.size(); i++) {
        data.push_back(elements[i]);
    }
}

template <typename T> 
Matrix<T>::Matrix(const Matrix<T>& matrix) {
    rows = matrix.rows;
    cols = matrix.cols;

    data.clear();
    for(unsigned int i = 0; i < matrix.data.size(); i++) {
        data.push_back(matrix.data[i]);
    }
}


template <typename T>
void Matrix<T>::print() {
    for(unsigned int i = 0; i < data.size(); i++) {
        std::cout << data[i] << ", ";
        if((i+1) % cols == 0)
            std::cout << std::endl;
    }
}

template <typename T>
Matrix<T> Matrix<T>::transpose() {
    std::vector<T> vec;
    for(unsigned int i = 0; i < data.size(); i++) {
        vec.push_back(data[(cols*(i%rows)+i/rows)]);
    }
    return Matrix<T>(vec, cols, rows);
}

template <typename T>
Matrix<T> Matrix<T>::dot(const Matrix<typename std::remove_reference<T>::type> & rhs) {
    if(cols != rhs.rows) {
        std::cout << "Error! Can not resolve dot product on these matrices!" << std::endl;
        std::cout << "Requested: [" << rows << "x" << cols << "] <alt+7> [" << rhs.rows << "x" << rhs.cols << "]" << std::endl;
        Matrix<T> matrix;
        return matrix;
    }

    Matrix<T> matrix;
    return matrix;
}

顯示的代碼有兩個問題。

1)復制構造函數錯誤:

Matrix(Matrix<T>&);

復制構造函數必須將const引用作為參數:

Matrix(const Matrix<T>&);

頭文件中的實際聲明也需要更改。

2)第二個問題是令人煩惱的解析

Matrix<T> matrix();
return matrix;

這應該簡單地改為:

Matrix<T> matrix;
return matrix;

或者只是為了:

return Matrix<T>();

這發生在所示代碼中的兩個位置。

一旦修復了上述兩個問題,顯示的代碼就會為我編譯,使用gcc 8。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM