I am writing a class for a mathematical vector.
The class was fine, but when I tried to change the implementation of the operator*
(dot product) to work with threads, I got some errors and I don't have any idea of how to fix them.
Code is below, I omitted the implementation of some functions I deemed unnecessary:
matVec.h
#ifndef ATLIB_MATVEC
#define ATLIB_MATVEC
#include <vector>
#include <iostream>
#include <cmath>
#include <thread>
namespace atlib{
template <class T>
class matVec{
public:
matVec();
matVec(size_t n);
matVec(size_t n, bool vert);
matVec(size_t n, T cons);
matVec(size_t n, T cons, bool vert);
~matVec();
int Size() const; //tested
bool Colm() const; //tested
static T Precision();
void push_back(T cons);
bool operator==(const matVec& mv) const; //tested
matVec operator+(const matVec& mv) const; //tested
matVec operator-() const &; //tested
matVec operator*(const T& scalar) const; //tested
T operator*(const matVec& mv) const; //tested
matVec operator-(const matVec& mv) const; //tested
T& operator[](std::size_t n); //tested
matVec Transpose();
atlib::matVec<T> operator=(matVec<T> mv);
atlib::matVec<T> Copy() const;
void push(T val);
friend std::ostream& operator<<(std::ostream& os, const matVec<T>& vec){
if (vec.Colm()){
for (const T& element : vec.data_) {
os << element << '\n';
}
}else{
size_t n = vec.data_.size();
for (size_t i = 0;i<n-1;i++) {
os << vec.data_[i] << "; ";
}
os << vec.data_[n-1];
}
return os;
}
private:
static T prec_;
std::vector<T> data_;
size_t size_;
bool col_;
};
}
template class atlib::matVec<int>;
template class atlib::matVec<double>;
//NON-Member functions
template<class T>
atlib::matVec<T> operator*(T scalar,atlib::matVec<T> mv){
return mv*scalar;
}
template<class T>
void thread_dotprod(atlib::matVec<T> &v, atlib::matVec<T> &w, unsigned int start, unsigned int end, T& t_ans);
#endif //ATLIB_MATVEC
matVec.cpp
#include <thread>
#include <pthread.h>
#include <vector>
#include "matVec.h"
template<>
double atlib::matVec<double>::prec_ = 0.00001;
template<>
int atlib::matVec<int>::prec_ = 0;
template<class T>
atlib::matVec<T>::matVec():size_(0),data_(std::vector<T>()),col_(true){
//blank
}
template<class T>
atlib::matVec<T>::matVec(size_t n):size_(n),data_(std::vector<T>()),col_(true){
data_.resize(n);
}
template<class T>
atlib::matVec<T>::matVec(size_t n, bool vert):size_(n),data_(std::vector<T>()),col_(vert){
data_.resize(n);
}
template<class T>
atlib::matVec<T>::matVec(size_t n, T cons):size_(n),data_(std::vector<T>(n,cons)),col_(true){
//blank
}
template<class T>
atlib::matVec<T>::matVec(size_t n, T cons, bool vert):size_(n),data_(std::vector<T>(n,cons)),col_(vert){
//blank
}
template<class T>
void thread_dotprod(atlib::matVec<T> &v, atlib::matVec<T> &w, unsigned int start, unsigned int end, T& t_ans){
t_ans = 0;
for(unsigned int i = start; i<end; i++){
t_ans += v[i]*w[i];
}
}
template<class T>
T atlib::matVec<T>::operator*(const atlib::matVec<T>& mv) const{
try{
bool works = (size_ == mv.Size());
if(!works) throw std::out_of_range("The sizes of the vectors aren't equal");
} catch(const std::out_of_range& ex){
std::cout<<"Exception: "<<ex.what()<<std::endl;
}
const unsigned int cores = std::thread::hardware_concurrency();
T ans = 0;
if (cores==0){
for(size_t i = 0;i<size_;i++){
ans += data_[i]*mv[i];
}
return ans;
}
std::vector<std::thread> threads;
unsigned int slice = size_/cores;
std::vector<T> t_ans_vec;
t_ans_vec.push_back(0);
T t_ans = t_ans_vec[0];
threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), (cores-1)*slice, size_, std::ref(t_ans)));
for(unsigned int i = 0; i<cores-1; i++){
t_ans_vec.push_back(0);
t_ans = t_ans_vec[i+1];
threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), i*slice, (i+1)*slice), std::ref(t_ans));
}
for (unsigned int i = 0; i<cores; i++){
threads[i].join();
ans+=t_ans_vec[i];
}
return ans;
}
The errors:
source/matVec.cpp: In instantiation of ‘T atlib::matVec<T>::operator*(const atlib::matVec<T>&) const [with T = int]’:
./header/matVec.h:56:23: required from here
source/matVec.cpp:120:31: error: passing ‘const atlib::matVec<int>’ as ‘this’ argument discards qualifiers [-fpermissive]
120 | ans += data_[i]*mv[i];
| ~~^
In file included from source/matVec.cpp:4:
./header/matVec.h:28:12: note: in call to ‘T& atlib::matVec<T>::operator[](std::size_t) [with T = int; std::size_t = long unsigned int]’
28 | T& operator[](std::size_t n); //tested
| ^~~~~~~~
source/matVec.cpp:129:28: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, std::reference_wrapper<const atlib::matVec<int> >, std::reference_wrapper<const atlib::matVec<int> >, unsigned int, const size_t&, std::reference_wrapper<int>)’
129 | threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), (cores-1)*slice, size_, std::ref(t_ans)));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/thread:43,
from source/matVec.cpp:1:
/usr/include/c++/11/bits/std_thread.h:127:7: note: candidate: ‘template<class _Callable, class ... _Args, class> std::thread::thread(_Callable&&, _Args&& ...)’
127 | thread(_Callable&& __f, _Args&&... __args)
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:127:7: note: template argument deduction/substitution failed:
source/matVec.cpp:129:28: note: couldn’t deduce template parameter ‘_Callable’
129 | threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), (cores-1)*slice, size_, std::ref(t_ans)));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/thread:43,
from source/matVec.cpp:1:
/usr/include/c++/11/bits/std_thread.h:157:5: note: candidate: ‘std::thread::thread(std::thread&&)’
157 | thread(thread&& __t) noexcept
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:157:5: note: candidate expects 1 argument, 6 provided
/usr/include/c++/11/bits/std_thread.h:121:5: note: candidate: ‘std::thread::thread()’
121 | thread() noexcept = default;
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:121:5: note: candidate expects 0 arguments, 6 provided
source/matVec.cpp:134:32: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, std::reference_wrapper<const atlib::matVec<int> >, std::reference_wrapper<const atlib::matVec<int> >, unsigned int, unsigned int)’
134 | threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), i*slice, (i+1)*slice), std::ref(t_ans));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/thread:43,
from source/matVec.cpp:1:
/usr/include/c++/11/bits/std_thread.h:127:7: note: candidate: ‘template<class _Callable, class ... _Args, class> std::thread::thread(_Callable&&, _Args&& ...)’
127 | thread(_Callable&& __f, _Args&&... __args)
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:127:7: note: template argument deduction/substitution failed:
source/matVec.cpp:134:32: note: couldn’t deduce template parameter ‘_Callable’
134 | threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), i*slice, (i+1)*slice), std::ref(t_ans));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/thread:43,
from source/matVec.cpp:1:
/usr/include/c++/11/bits/std_thread.h:157:5: note: candidate: ‘std::thread::thread(std::thread&&)’
157 | thread(thread&& __t) noexcept
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:157:5: note: candidate expects 1 argument, 5 provided
/usr/include/c++/11/bits/std_thread.h:121:5: note: candidate: ‘std::thread::thread()’
121 | thread() noexcept = default;
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:121:5: note: candidate expects 0 arguments, 5 provided
source/matVec.cpp: In instantiation of ‘T atlib::matVec<T>::operator*(const atlib::matVec<T>&) const [with T = double]’:
./header/matVec.h:57:23: required from here
source/matVec.cpp:120:31: error: passing ‘const atlib::matVec<double>’ as ‘this’ argument discards qualifiers [-fpermissive]
120 | ans += data_[i]*mv[i];
| ~~^
In file included from source/matVec.cpp:4:
./header/matVec.h:28:12: note: in call to ‘T& atlib::matVec<T>::operator[](std::size_t) [with T = double; std::size_t = long unsigned int]’
28 | T& operator[](std::size_t n); //tested
| ^~~~~~~~
source/matVec.cpp:129:28: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, std::reference_wrapper<const atlib::matVec<double> >, std::reference_wrapper<const atlib::matVec<double> >, unsigned int, const size_t&, std::reference_wrapper<double>)’
129 | threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), (cores-1)*slice, size_, std::ref(t_ans)));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/thread:43,
from source/matVec.cpp:1:
/usr/include/c++/11/bits/std_thread.h:127:7: note: candidate: ‘template<class _Callable, class ... _Args, class> std::thread::thread(_Callable&&, _Args&& ...)’
127 | thread(_Callable&& __f, _Args&&... __args)
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:127:7: note: template argument deduction/substitution failed:
source/matVec.cpp:129:28: note: couldn’t deduce template parameter ‘_Callable’
129 | threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), (cores-1)*slice, size_, std::ref(t_ans)));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/thread:43,
from source/matVec.cpp:1:
/usr/include/c++/11/bits/std_thread.h:157:5: note: candidate: ‘std::thread::thread(std::thread&&)’
157 | thread(thread&& __t) noexcept
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:157:5: note: candidate expects 1 argument, 6 provided
/usr/include/c++/11/bits/std_thread.h:121:5: note: candidate: ‘std::thread::thread()’
121 | thread() noexcept = default;
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:121:5: note: candidate expects 0 arguments, 6 provided
source/matVec.cpp:134:32: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, std::reference_wrapper<const atlib::matVec<double> >, std::reference_wrapper<const atlib::matVec<double> >, unsigned int, unsigned int)’
134 | threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), i*slice, (i+1)*slice), std::ref(t_ans));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/thread:43,
from source/matVec.cpp:1:
/usr/include/c++/11/bits/std_thread.h:127:7: note: candidate: ‘template<class _Callable, class ... _Args, class> std::thread::thread(_Callable&&, _Args&& ...)’
127 | thread(_Callable&& __f, _Args&&... __args)
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:127:7: note: template argument deduction/substitution failed:
source/matVec.cpp:134:32: note: couldn’t deduce template parameter ‘_Callable’
134 | threads.push_back(std::thread(thread_dotprod, std::ref(*this), std::ref(mv), i*slice, (i+1)*slice), std::ref(t_ans));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/thread:43,
from source/matVec.cpp:1:
/usr/include/c++/11/bits/std_thread.h:157:5: note: candidate: ‘std::thread::thread(std::thread&&)’
157 | thread(thread&& __t) noexcept
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:157:5: note: candidate expects 1 argument, 5 provided
/usr/include/c++/11/bits/std_thread.h:121:5: note: candidate: ‘std::thread::thread()’
121 | thread() noexcept = default;
| ^~~~~~
/usr/include/c++/11/bits/std_thread.h:121:5: note: candidate expects 0 arguments, 5 provided
make: *** [Makefile:34: objects/matVec.o] Error 1