Cannot convert from *const to & in += operator [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I was staring at this all night before I decided to give up and go to sleep - a few hours into it again today, I still don't have it. I am unable to figure out how to change the const-ness and parameters to correctly return (on the operator+=). Any help?
The error pops up at the return this statement in the operator+= overload.
#include <iostream>
#include <vector>
template <typename T> class Matrix {
private:
unsigned rows, cols;
public:
Matrix();
~Matrix();
Matrix(const Matrix<T>& rhs);
Matrix(unsigned _rows, unsigned _cols);
std::vector<std::vector<T>> matrix;
Matrix<T>& operator=(Matrix<T> rhs);
//Matrix mathematical operations
Matrix<T> operator+(const Matrix<T>& rhs);
Matrix<T>& operator+=(const Matrix<T>& rhs);
// Access the individual elements
T& operator()(const unsigned& row, const unsigned& col);
const T& operator()(const unsigned& row, const unsigned& col) const;
// Access the row and column sizes
unsigned get_rows() const;
unsigned get_cols() const;
void swap(Matrix<T>& rhs);
};
template<typename T>
Matrix<T>::Matrix() {}
template<typename T>
Matrix<T>::~Matrix() {}
// Parameter Constructor
template<typename T>
Matrix<T>::Matrix(unsigned _rows, unsigned _cols) {
matrix.resize(_rows);
for (unsigned i = 0; i < _rows; i++)
matrix[i].resize(_cols, 1); // change back to 0 after debug
rows = _rows;
cols = _cols;
}
template<typename T>
Matrix<T>& Matrix<T>::operator=(Matrix<T> rhs) {
swap(rhs);
return *this;
}
template<typename T>
Matrix<T> Matrix<T>::operator+(const Matrix<T>& rhs) {
Matrix<T> result(*this);
result += rhs;
return result;
}
template<typename T>
Matrix<T>& Matrix<T>::operator+=(const Matrix<T>& rhs) {
for (unsigned i = 0; i < rows; i++) {
for (unsigned j = 0; j < cols; j++) {
this->matrix[i][j] += rhs(i, j);
}
}
return this; // error pops up here
}
// Access the individual elements
template<typename T>
T& Matrix<T>::operator()(const unsigned& row, const unsigned& col) {
return this->matrix[row][col];
}
// Access the individual elements (const)
template<typename T>
const T& Matrix<T>::operator()(const unsigned& row, const unsigned& col) const{
return this->matrix[row][col];
}
// Get the number of rows of the matrix
template<typename T>
unsigned Matrix<T>::get_rows() const {
return this->rows;
}
//Get the number of columns of the matrix
template<typename T>
unsigned Matrix<T>::get_cols() const {
return this->cols;
}
template<typename T>
void Matrix<T>::swap(Matrix<T>& rhs) {
using std::swap;
swap(this->rows, rhs.rows);
swap(this->cols, rhs.cols);
swap(this->matrix, rhs.matrix);
}
// for debugging
template<typename T>
void print_matrix(Matrix<T>& matrix) {
for (int i = 0; i < matrix.get_rows(); i++) {
for (int j = 0; j < matrix.get_cols(); j++) {
std::cout << matrix(i, j) << " ";
}
std::cout << " " << std::endl;
}
}
int main(int argc, char **argv) {
Matrix<double> matrix1(5, 5);
Matrix<double> matrix2(5, 5);
// Start testing
Matrix<double> matrix3 = matrix1 + matrix2;
print_matrix(matrix1);
std::getchar();
return 0;
}

In the += operator, you probably want:
Matrix<T>& Matrix<T>::operator+=(const Matrix<T>& rhs) {
//....
return *this;
//^^
}
The linker error is because you did not define:
Matrix(const Matrix<T>& rhs);

Related

Use of common_type_t and enable_if for generic matrix class (via expression template)

I am writing a matrix library for generic types using expression templates.
The basic matrix class is a template class Matrix <typename Scalar, int RowSize, int ColumnSize>
which inherits from MatrixXpr< Matrix<Scalar, RowSize, ColumnSize> >
where MatrixXpr is the parent class for the expression templates "MatrixSum", "MatrixProduct" etc.
For example:
template <typename Mat, typename Rix>
class MatrixProduct : public MatrixXpr< MatrixProduct<Mat,Rix> >
{
private:
const Mat& A_;
const Rix& B_;
public:
using value_type= std::common_type_t<typename Mat::value_type, typename Rix::value_type>;
MatrixProduct(const Mat& A, const Rix& B) : A_(A), B_(B) {}
value_type operator()(int i, int j) const {
value_type out{ 0 };
for (int k = 0; k < A_.Columns(); ++k) out += A_(i, k) * B_(k, j);
return out;
}
};
The * operator is then defined outside
template <typename Mat, typename Rix>
MatrixProduct<Mat, Rix> inline const operator*(const MatrixXpr<Mat>& A, const MatrixXpr<Rix>& B)
{
return MatrixProduct<Mat, Rix>(A, B);
}
Now I wish to implement also a Scalar*Matrix class. But I fail to define the correct value_type:
template <typename Scalar, typename Mat>
class ScalarMatrixProduct : public MatrixXpr< ScalarMatrixProduct<Scalar, Mat> >
{
private:
const Scalar& A_;
const Mat& B_;
public:
using value_type = std::common_type_t<typename Mat::value_type, typename Scalar>;
ScalarMatrixProduct(const Scalar& A, const Mat& B) : A_(A), B_(B) {}
value_type operator()(int i, int j) const {
return A_ * B_(i, j);
}
};
template <typename Scalar, typename Mat>
typename std::enable_if < (!is_matrix<Scalar>::value),
ScalarMatrixProduct<Scalar, Mat > >::type const operator*(const Scalar& A, const MatrixXpr<Mat>& B)
{
return ScalarMatrixProduct<Scalar, Mat>(A, B);
}
On Mac and Linux I get an compilation error of this sort:
template argument 2 is invalid 102 | using value_type =
std::common_type_t<typename Mat::value_type, typename Scalar>;
Interestingly, it compiles on Windows.
Any hints for what's wrong would be helpful.
Thanks in advance.
Complete example:
#include <type_traits>
#include <iostream>
#include <array>
#include <initializer_list>
///////////Expression Template Base Class for CRTP
template <class MatrixClass> struct MatrixXpr {
decltype(auto) operator()(int i, int j) const {
return static_cast<MatrixClass const&>(*this)(i, j);
}
operator MatrixClass& () {
return static_cast<MatrixClass&>(*this);
}
operator const MatrixClass& () const {
return static_cast<const MatrixClass&>(*this);
}
int Rows()
{
return static_cast<MatrixClass&>(*this).Rows();
}
int Columns()
{
return static_cast<MatrixClass&>(*this).Columns();
}
int Rows() const
{
return static_cast<const MatrixClass&>(*this).Rows();
}
int Columns() const
{
return static_cast<const MatrixClass&>(*this).Columns();
}
friend int Rows(const MatrixXpr& A)
{
return A.Rows();
}
friend int Columns(const MatrixXpr& A)
{
return A.Columns();
}
};
template <typename MatrixClass>
std::ostream& operator<<(std::ostream& os, const MatrixXpr<MatrixClass>& A)
{
for (int r = 0; r < Rows(A); ++r) {
os << '[';
for (int c = 0; c < Columns(A); ++c)
os << A(r, c) << (c + 1 < Columns(A) ? " " : "");
os << "]\n";
}
return os;
}
/////////// Matrix Product
template <typename Mat, typename Rix>
class MatrixProduct : public MatrixXpr< MatrixProduct<Mat, Rix> >
{
private:
const Mat& A_;
const Rix& B_;
public:
using value_type = std::common_type_t<typename Mat::value_type, typename Rix::value_type>;
MatrixProduct(const Mat& A, const Rix& B) : A_(A), B_(B)
{
std::cout << "MatrixMatrixProduct Constructor\n";
}
int Rows() const { return A_.Rows(); }
int Columns() const { return B_.Columns(); }
value_type operator()(int i, int j) const {
value_type out{ 0 };
for (int k = 0; k < A_.Columns(); ++k) out += A_(i, k) * B_(k, j);
return out;
}
};
/////////// Scalar Matrix Product
template <typename Scalar, typename Mat>
class ScalarMatrixProduct : public MatrixXpr< ScalarMatrixProduct<Scalar, Mat> >
{
private:
const Scalar& A_;
const Mat& B_;
public:
using value_type = std::common_type_t<typename Mat::value_type, typename Scalar>;
ScalarMatrixProduct(const Scalar& A, const Mat& B) : A_(A), B_(B) {
std::cout << "ScalarMatrixProduct Constructor\n";
}
int Rows() const { return B_.Rows(); }
int Columns() const { return B_.Columns(); }
value_type operator()(int i, int j) const {
return A_ * B_(i, j);
}
};
//The following two functions are Helpers for initializing an array.
//Source: https://stackoverflow.com/a/38934685/6176345
template<typename T, std::size_t N, std::size_t ...Ns>
std::array<T, N> make_array_impl(
std::initializer_list<T> list,
std::index_sequence<Ns...>)
{
return std::array<T, N>{ *(list.begin() + Ns) ... };
}
template<typename T, std::size_t N>
std::array<T, N> make_array(std::initializer_list<T> list) {
if (N > list.size())
throw std::out_of_range("Initializer list too small.");
return make_array_impl<T, N>(list, std::make_index_sequence<N>());
}
/////////// Matrix class
template <typename Scalar, int RowSize, int ColumnSize = RowSize>
class Matrix : public MatrixXpr< Matrix<Scalar, RowSize, ColumnSize> >
{
std::array<Scalar, RowSize* ColumnSize> data_;
public:
using value_type = Scalar;
const static int rows_ = RowSize;
const static int columns_ = ColumnSize;
int Rows() const { return rows_; }
int Columns() const { return columns_; }
Matrix() : data_{ Scalar(0) } {};
Matrix(const Matrix& other) = default;
Matrix(Matrix&& other) = default;
Matrix& operator=(const Matrix& other) = default;
Matrix& operator=(Matrix&& other) = default;
~Matrix() = default;
Matrix(std::initializer_list<Scalar> data) : data_(make_array<Scalar, RowSize* ColumnSize>(data)) {}
template <typename Source>
Matrix& operator=(const MatrixXpr<Source>& source)
{
for (int i = 0; i < rows_; ++i)
for (int j = 0; j < columns_; ++j)
data_[MatrixIndex(i, j)] = source(i, j);
return *this;
}
template <typename Source>
Matrix(const MatrixXpr<Source>& source)
{
for (int i = 0; i < rows_; ++i)
for (int j = 0; j < columns_; ++j)
data_[MatrixIndex(i, j)] = source(i, j);
}
Scalar& operator()(int i, int j) {
return data_[MatrixIndex(i, j)];
}
const Scalar& operator()(int i, int j) const {
return data_[MatrixIndex(i, j)];
}
private:
inline static int MatrixIndex(int i, int j)
{
return i * columns_ + j;
}
};
/////////// Multiplication operators
template <typename Mat, typename Rix>
MatrixProduct<Mat, Rix> inline const operator*(const MatrixXpr<Mat>& A, const MatrixXpr<Rix>& B)
{
std::cout << "Matrix Matrix Multiplication\n";
return MatrixProduct<Mat, Rix>(A, B);
}
template <typename Scalar, typename Mat>
typename std::enable_if_t<!std::is_base_of_v<MatrixXpr<Scalar>, Scalar>,
ScalarMatrixProduct<Scalar, Mat >> const operator*(const Scalar& A, const MatrixXpr<Mat>& B)
{
return ScalarMatrixProduct<Scalar, Mat>(A, B);
}
/////////// Failing example
int main()
{
Matrix<int, 2, 2> m = { 1,0,0,1 };
auto n = 3 * m;
std::cout << n;
std::cout << m * n;
//std::cout << n * m; // Error
return 0;
}
Edit:
The above code originally had two problems.
The first one is that my type checking failed to see which overload of the *operator was being used. The above implementation with std::is_base_of_v<MatrixXpr<Scalar>, Scalar> fixed it and is is working correctly.
I do not know why this old code did not work. Here is the old version:
template <typename T>
struct is_matrix : std::false_type {};
template <typename T>
struct is_matrix<const T> : is_matrix<T> {};
template <typename MatrixClass>
struct is_matrix<MatrixXpr<MatrixClass> > : std::true_type {};
template <typename Scalar, typename Mat>
typename std::enable_if < (!is_matrix<Scalar>::value),
ScalarMatrixProduct<Scalar, Mat > >::type const operator*(const Scalar& A, const MatrixXpr<Mat>& B)
{
std::cout << "Scalar Matrix Multiplication\n";
return ScalarMatrixProduct<Scalar, Mat>(A, B);
}

Operator overloading in matrix using expression templates

I have been trying to figure out expression templates since the last couple of days but haven't been able to get past this. I am building a matrix starting with the add operator. I am building using c++14.
My matrix.h looks like this:
template <typename T, std::size_t COL, std::size_t ROW>
class Matrix {
public:
using value_type = T;
Matrix() : values(COL * ROW) {}
static size_t cols() { return COL; }
static size_t rows() { return ROW; }
const T& operator()(size_t x, size_t y) const { return values[y * COL + x]; }
T& operator()(size_t x, size_t y) { return values[y * COL + x]; }
template <typename E>
Matrix<T, COL, ROW>& operator=(const E& expression) {
for (std::size_t y = 0; y != rows(); ++y) {
for (std::size_t x = 0; x != cols(); ++x) {
values[y * COL + x] = expression(x, y);
}
}
return *this;
}
private:
std::vector<T> values;
};
template <typename LHS, typename RHS>
class MatrixSum
{
public:
using value_type = typename LHS::value_type;
MatrixSum(const LHS& lhs, const RHS& rhs) : rhs(rhs), lhs(lhs) {}
value_type operator() (int x, int y) const {
return lhs(x, y) + rhs(x, y);
}
private:
const LHS& lhs;
const RHS& rhs;
};
template <typename LHS, typename RHS>
MatrixSum<LHS, RHS> operator+(const LHS& lhs, const LHS& rhs) {
return MatrixSum<LHS, RHS>(lhs, rhs);
}
Cpp file main function looks contains this:
Matrix<int,5,5>mx,my;
mx+my;
This shows the following error:
invalid operands to binary expression ('Matrix<int, 5, 5>' and 'Matrix<int, 5, 5>')
mx+my;
I have searched a lot online, but I clearly have missed something. The above code is taken from https://riptutorial.com/cplusplus/example/19992/a-basic-example-illustrating-expression-templates.
I would appreciate if some resources to understand expression templates can be shared.

Overloading ostream operator in custom class

I am trying to play with CRTP with a custom matrix class. Now I am trying to overloading the ostream operator, follow https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx.
However, everything seems to be compiling but the program never exists and prints nothing on the screen. I am scratching my head as what is happening.
Anyway, this is the relevant code (Sorry it is a bit lengthy)
#ifndef EXPERIMENT_POINTERMATRIX_H
#define EXPERIMENT_POINTERMATRIX_H
#include <cstdlib>
#include <ostream>
#include "macro.h"
namespace PM {
template<typename T, typename Derived>
class MatrixBase{
public:
size_t nRow;
size_t nCol;
MatrixBase(const size_t nRow_,const size_t nCol_):nRow(nRow_), nCol(nCol_){}
Derived& derived(){
return *static_cast<Derived*>(this);
}
const Derived& derived() const{
return *static_cast<Derived*>(this);
}
T& operator()(const size_t i, const size_t j){
CHECK_BOUND(i,j,*this);
return derived().operator()(i,j);
}
const T& operator()(const size_t i, const size_t j) const {
return const_cast<T&>(
static_cast<const MatrixBase<T, Derived>&>(*this).operator()(i,j));
}
inline T rows(){
return nRow;
}
const T rows() const {
return nRow;
}
inline T cols(){
return nCol;
}
const T cols() const {
return nCol;
}
template<typename t1, typename t2>
friend std::ostream& operator<<(std::ostream& os, const MatrixBase<t1, t2> & matrix);
};
template<typename t1, typename t2>
std::ostream& operator<<(std::ostream& os, const MatrixBase<t1, t2>& matrix){
for (size_t i =0;i<matrix.rows();i++){
os << matrix(i,0);
if (matrix.cols()>1) {
for (size_t j = 1; j < matrix.cols(); j++) {
os << "," << matrix(i, j);
}
}
os << std::endl;
}
return os;
};
template<typename T, typename Derived>
class Matrix : public MatrixBase<T, Matrix<T, Derived>>{
public:
T * data;
Matrix(const size_t nRow, const size_t nCol):MatrixBase<T, Matrix<T, Derived>>(nRow, nCol){
data = (T*) malloc(sizeof(T)*nRow*nCol);
}
~Matrix(){
free(data);
}
Derived& derived(){
return *static_cast<Derived*>(this);
}
const Derived& derived() const{
return *static_cast<Derived*>(this);
}
T& operator()(const size_t i, const size_t j){
return derived().operator()(i,j);
}
};
template<typename T, typename Derived>
class MatrixView : public MatrixBase<T, MatrixView<T, Derived>>{
public:
T * data;
MatrixView(const size_t nRow, size_t nCol, T * other):MatrixBase<T, MatrixView<T, Derived>>(nRow, nCol), data(other){}
T& operator()(const size_t i, const size_t j){
return derived().operator()(i,j);
}
Derived& derived(){
return *static_cast<Derived*>(this);
}
const Derived& derived() const{
return *static_cast<Derived*>(this);
}
};
template<typename T>
class MatrixRowMajor: public Matrix<T, MatrixRowMajor<T>>{
public:
MatrixRowMajor(const size_t nRow, const size_t nCol):Matrix<T, MatrixRowMajor<T>>(nRow, nCol){}
T& operator()(const size_t i, const size_t j){
using base = MatrixBase<T, Matrix<T, MatrixRowMajor<T>>>;
using super = Matrix<T, MatrixRowMajor<T>>;
return super::data[i*base::nCol+j];
}
};
template<typename T>
class MatrixColMajor: public Matrix<T, MatrixColMajor<T>>{
public:
MatrixColMajor(const size_t nRow, const size_t nCol):Matrix<T, MatrixColMajor<T>>(nRow, nCol){}
T& operator()(const size_t i, const size_t j){
using base = MatrixBase<T, Matrix<T, MatrixColMajor<T>>>;
using super = Matrix<T, MatrixColMajor<T>>;
return super::data[i+j*base::nRow];
}
};
template<typename T>
class MatrixViewRowMajor : public MatrixView<T, MatrixViewRowMajor<T>>{
public:
MatrixViewRowMajor(const size_t nRow, const size_t nCol, T* other):MatrixView<T, MatrixViewRowMajor<T>>(nRow, nCol, other){}
T& operator()(const size_t i, const size_t j){
using base = MatrixBase<T, Matrix<T, MatrixViewRowMajor<T>>>;
using super = MatrixView<T, MatrixViewRowMajor<T>>;
return super::data[i*base::nCol+j];
}
};
template<typename T>
class MatrixViewColMajor : public MatrixView<T, MatrixViewColMajor<T>>{
public:
MatrixViewColMajor(const size_t nRow, const size_t nCol, T* other):MatrixView<T, MatrixViewRowMajor<T>>(nRow, nCol, other){}
T& operator()(const size_t i, const size_t j){
using base = MatrixBase<T, Matrix<T, MatrixViewRowMajor<T>>>;
using super = MatrixView<T, MatrixViewRowMajor<T>>;
return super::data[i+j*base::nRow];
}
};
}
void test_print(){
using namespace PM;
using namespace std;
MatrixRowMajor<double> matrix(10, 1);
for (int i =0;i<matrix.rows();i++){
matrix(i,0)=1.0;
std::cout << "i'th entry is " <<matrix(i,0) << std::endl; //This is fine
}
std::cout << matrix; //This is not fine
}
#endif //EXPERIMENT_POINTERMATRIX_H
The whole program is compiled using g++4.9 (enabling c++11)
EDIT:
In order to test whether it is the problem of the operator, I create the following methods (at MatrixBase):
void print(){
for (size_t i =0;i<this->rows();i++){
std::cout << this->operator()(i,0);
if (this->cols()>1) {
for (size_t j = 1; j < this->cols(); j++) {
std::cout << "," << this->operator()(i, j);
}
}
std::cout << std::endl;
}
}
and call the methods like matrix.print(). This works as expected.
Unfortunately, the debugger gives no useful information as the program stops in the line os << matrix(i,0), and when I stop the program to retrieve the information, it says fails to get the frame (Clion as debugger)
The (member function of MatrixBase) operator() unconditionally calls itself, so is infinitely recursive.
const T& operator()(const size_t i, const size_t j) const {
return const_cast<T&>(
static_cast<const MatrixBase<T, Derived>&>(*this).operator()(i,j));
}
This function is tail-recursive, so can result in an infinite loop rather than crashing due to great call depths.
Unrelated to your question, it is usually considered inadvisable to use malloc() in C++ - particularly when working with types (e.g. C++ classes) that may not be directly compatible with C - results, for the user of your class, depending on the type T, can be undefined. Use operator new instead. Even better, use a standard container.

Custom Vector Class: Failure to Return After Sum

Related to this question that I asked yesterday.
I'm building my own vector class to learn a little more about C++, and I'm having some difficulty implementing an overloaded operator+ that I can use to add vectors. Here's what my class looks like so far:
template<typename T>
class vector;
template<typename T>
vector<T> operator+(const vector<T>&, const vector<T>&);
template<typename T>
class vector
{
private:
T* pointer_;
unsigned long size_;
public:
// Constructors and destructors.
vector();
template<typename A> vector(const A&);
template<typename A> vector(const A&, const T&);
vector(const vector<T>&);
~vector();
// Methods.
unsigned long size();
T* begin();
T* end();
vector<T>& push_back(const T&);
// Operators.
T operator[](unsigned long);
vector<T>& operator=(const vector<T>&);
friend vector<T> operator+<>(const vector<T>&, const vector<T>&);
};
template<typename T>
vector<T> operator+(const vector<T>& lhs, const vector<T>& rhs)
{
vector<T> result(lhs.size_);
for (unsigned long i = 0; i != result.size_; i++)
{
result.pointer_[i] = lhs.pointer_[i] + rhs.pointer_[i];
}
return result;
}
The constructor vector(const A& size, const T& value) operates as expected, returning a vector with size elements initialized to value. operator= appears to be working, as well. When I try something like this, however, my program doesn't perform as expected:
#include <iostream>
#include "vector.h"
int main()
{
vector<int> test(5, 2); // Create a vector with five elements initialized to 2.
vector<int> test2(5, 3); // Create a vector with five elements initialized to 3.
std::cout << test.size() // Prints 5, as expected.
std::cout << test2.size() // Prints 5, as expected.
vector<int> try_result = test + test2;
std::cout << try_result.size() // Prints 0--why?
}
My question: if operator+ returns a copy of result (and not by reference, a problem that originally existed in my code), why does it appear that try_result still does not point to the proper location in the heap?
EDIT: Adding the constructor code (I've tested this, and it seems to work, but maybe for the wrong reasons):
template<typename T> template<typename A>
vector<T>::vector(const A& size)
{
this->pointer_ = new T[size];
this->size_ = size;
}
template<typename T> template<typename A>
vector<T>::vector(const A& size, const T& initial_value)
{
this->pointer_ = new T[size];
this->size_ = size;
for (unsigned long i = 0; i != this->size_; i++)
{
pointer_[i] = initial_value;
}
}
EDIT2: Adding the copy constructor.
template<typename T>
vector<T>::vector(const vector<T>& replicate_vector)
{
delete[] this->pointer_;
this->pointer_ = new T[replicate_vector.size_];
this->size_ = replicate_vector.size_;
for (unsigned long i = 0; i != this->size_; i++)
{
this->pointer_[i] = replicate_vector.pointer_[i];
}
}

C++ second template in single template class

I am developing a matrix class for my personal library. I am using a template class (Class T) because I want a matrix to be of any numeric or boolean format (and don't want to retype everything). So what I would like to do is have the operater+= allow a scalar or a matrix. However, I would like to be able to add two matrices together regardless of their numeric format (Class U).
I get the following compile errors.
error: prototype for 'JecMatrix<T>& JecMatrix<T>::operator+=(const JecMatrix<U>&)' does not match any in class 'JecMatrix<T>'
error: candidates are: template<class T> template<class U> JecMatrix& JecMatrix::operator+=(const U&)
error: template<class T> template<class U> JecMatrix& JecMatrix::operator+=(const JecMatrix<U>&)
Does anyone have a solution to this? I've included the entire class below.
#ifndef JECMATRIX_H
#define JECMATRIX_H
#include <typeinfo>
#include <QTime>
#include <QList>
#include <JecLibrary_global.h>
#include <JecUtils.h>
template<class T>
class JECLIBRARYSHARED_EXPORT JecMatrix
{
public:
JecMatrix();
JecMatrix(const int& rows, const int& cols);
JecMatrix(const QList<QList<T> >& sourceMatrix);
~JecMatrix();
JecMatrix<T>& operator=(const JecMatrix<T>& rhs);
bool operator!=(const JecMatrix<T>& rhs) const;
bool operator==(const JecMatrix<T>& rhs) const;
template<class U> JecMatrix<T>& operator+=(const JecMatrix<U> &rhs) throw(QString);
template<class U> JecMatrix<T>& operator+=(const U& rhs) throw(QString);
};
template<class T>
JecMatrix<T>::JecMatrix()
{
T var;
assertNumber(var);
}
template<class T>
JecMatrix<T>::JecMatrix(const int &rows, const int &cols)
{
for (int r = 0; r < rows; ++r)
{
matrix.append(QList<T>());
for (int c = 0; c < cols; ++c)
{
matrix[r].append(0);
}
}
}
template<class T>
JecMatrix<T>::JecMatrix(const QList<QList<T> >& sourceMatrix)
{
for (int r = 0; r < sourceMatrix.length(); ++r)
{
matrix.append(QList<T>());
for (int c = 0; c < sourceMatrix.at(r).length(); ++c)
{
matrix[r].append(sourceMatrix.at(r).at(c));
}
}
}
template<class T>
JecMatrix<T>& JecMatrix<T>::operator=(const JecMatrix<T>& rhs)
{
if (this == &rhs)
{
return *this;
}
this->id = rhs.id; // The id of the Base.
this->minerals = rhs.minerals; // The minerals available at that base.
this->vespene = rhs.vespene; // The gas available at that base.
this->buildings = rhs.buildings; // The units the player owns during this second. The outer QList holds the types of units and the inner holdes the unique coppies of that unit.
this->units = rhs.units; // The units the player owns during this second. The outer QList holds the types of units and the inner holdes the unique coppies of that unit.
return *this;
}
template<class T,class U>
JecMatrix<T>& JecMatrix<T>::operator+=(const JecMatrix<U> &rhs) throw(QString)
{
// Perform type checking.
U var;
assertNumber(var);
// Perform size checking.
if (rhs.getRows() != getRows()) {
throw ("To add the matrices they must have the same number of rows and columns. Matrix a has "
+ QString::number(a.getRows())
+ " rows and matrix b has "
+ QString::number(b.getRows()) + " rows.");
}
if (rhs.getCols() != getCols()) {
throw ("To add the matrices they must have the same number of rows and columns. Matrix a has "
+ QString::number(a.getCols())
+ " cols and matrix b has "
+ QString::number(b.getCols()) + " cols.");
}
double result[][] = new double[a.getRows()][a.getCols()];
// Add the matrices.
for (int resultRow = 0; resultRow < a.getRows(); resultRow++) {
for (int resultCol = 0; resultCol < a.getCols(); resultCol++)
{
matrix[resultRow][resultCol] += rhs.matrix[resultRow][resultCol];
}
}
return *this;
}
template<class T, class U>
JecMatrix& JecMatrix::operator+=(const U& rhs) throw(QString)
{
// Perform type checking.
U var;
assertNumber(var);
// Perform the scalar addition.
for (int r = 0; r < matrix.length(); ++r)
{
for (int c = 0; c < matrix.at(0).length(); ++c)
{
matrix[r][c] += rhs;
}
}
}
#endif // JECMATRIX_H
Edit: removed irrelevant code.
Say it like this:
template <class T>
template <class U>
JecMatrix<T>& JecMatrix<T>::operator+=(const JecMatrix<U> &rhs) throw(QString)
{
// ...
}
The two template declarations have to be separate.