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 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…