Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
72 views
in Technique[技术] by (71.8m points)

c++ - Returning template class object

I have a template of a matrix class:

template <typename T>
class Matrix {

And many functions (like adding two matrices) return std::optional. I wanted to make an operator that would unwrap the value (or throw an exception):

template <class T>
Matrix<T> operator!(const std::optional<Matrix<T>>& other) {
    return other.value();
}

Doing that I get the error C2440: "Cannot convert from const _Ty to Matrix< int > with [ _Ty = Matrix]". It says that construction of Matrix class cannot be done because of ambiguous copying constructors or unavailable copying constructor.

EDIT:

#include <iostream>
#include <optional>

template <typename T>
class Matrix {
private:
    T** matrix;
    int sizeX;
    int sizeY;
public:
    Matrix(int x, int y);
    Matrix(Matrix<T>& other);
    Matrix(Matrix<T>&& other);

    void set_value(T val, int x, int y);
    std::optional<Matrix<T>> vec_from_col(int colIndex);
};

template <typename T>
Matrix<T>::Matrix(int x, int y) {

    std::cout << "Matrix Param
";

    if (x <= 0 || y <= 0) {
        return;
        throw -1;
    }
    else {
        matrix = new T*[x];
        for (int i = 0; i < x; i++) {
            matrix[i] = new T[y];
            for (int j = 0; j < y; j++) {
                matrix[i][j] = 0;
            }
        }
        sizeX = x;
        sizeY = y;
    }
}

template <typename T>
Matrix<T>::Matrix(Matrix<T>& other) {

    std::cout << "Matrix Copy
";

    sizeX = other.sizeX;
    sizeY = other.sizeY;
    matrix = new T*[sizeX];
    for (int i = 0; i < sizeX; i++) {
        matrix[i] = new T[sizeY];
        for (int j = 0; j < sizeY; j++) {
            matrix[i][j] = other.matrix[i][j];
        }
    }
}

template <typename T>
Matrix<T>::Matrix(Matrix<T>&& other) {

    std::cout << "Matrix Move
";

    sizeX = other.sizeX;
    sizeY = other.sizeY;
    matrix = other.matrix;
    other.matrix = NULL;
}

template <typename T>
void Matrix<T>::set_value(T val, int x, int y) {
    if (x < 0 || x >= sizeX || y < 0 || y >= sizeY) {
        std::cout << "Invalid index was given. Matrix was unchanged.
";
        return;
    }
    else {
        matrix[x][y] = val;
    }
}

template <typename T>
std::optional<Matrix<T>> Matrix<T>::vec_from_col(int colIndex) {

    if (colIndex < 0 || colIndex >= sizeX) {
        return {};
    }

    Matrix<T> newVec(1, sizeY);
    for (int i = 0; i < sizeY; i++) {
        newVec.set_value(matrix[colIndex][i], 0, i);
    }
    return newVec;
}

template <class T>
Matrix<T> operator!(const std::optional<Matrix<T>>& other) {
    return other.value();
}

int main() {
    Matrix<int> test(2, 3);
    test.set_value(10, 0, 1);
    test.set_value(5, 0, 0);
    test.set_value(13, 0, 2);
    test.set_value(8, 1, 0);
    Matrix<int> vec = !test.vec_from_col(0);
}
question from:https://stackoverflow.com/questions/65846765/returning-template-class-object

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your copy constructor is wrong which causes this ambiguity.

Matrix(Matrix<T>& other);

should be

Matrix(const Matrix<T>& other);

Note: You also leak memory since you new[] but don't delete[].


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...