I have this class which aims to mimic the behavior of a vector in MATLAB, I’m building this just as a college exercise.
#include <iostream>
#include <vector>
#include <tuple>
using namespace std;
double const pi = 3.141592;
class mv{
public:
mv(size_t size = 0, double init = 0) {for(size_t i = 0; i < size; i++) a.push_back(init);};
size_t size() const {return a.vector<double>::size();};
void print() const {for(auto &el : a) std::cout << el << " ";};
double get(size_t n) const {return a[n];};
double& operator[](size_t n) {return a[n];};
private:
vector<double> a;
};
I want to add the multiplication by a scalar and I want it to work in both ways, i.e. both a * 3
and 3 * a
should work as shown below.
int main() {
mv a(5, 1);
a[3] = 2;
mv b(5);
b = a * pi;
b.print();
cout << endl;
mv c(5);
c = pi * a;
c.print();
cout << endl;
return 0;
}
The most obvious way to do this is
mv operator*(const mv& a, const double& scalar){
mv res(a.size());
for(size_t i=0; i<a.size(); i++) res[i] = a.get(i) * scalar;
return res;
};
mv operator*(const double& scalar, const mv& a){
mv res(a.size());
for(size_t i=0; i<a.size(); i++) res[i] = a.get(i) * scalar;
return res;
};
But I would really like to do it with just one function, so I’ve explored this option
template<typename T, typename V>
mv operator*(const T& lhs, const V& rhs){
auto tuple = std::tie(lhs, rhs);
return mvTimes(std::get<const mv&>(tuple), std::get<const double&>(tuple));
};
mv mvTimes(const mv& a, const double& scalar){
mv res(a.size());
for(size_t i=0; i<a.size(); i++) res[i] = a.get(i) * scalar;
return res;
};
This works but feels clumsy and prone to errors (for example I should then have to catch exceptions thrown by std::get). What is the best way to do this?
You can define one operator in terms of the other:
mv operator*(const double& scalar, const mv& a){
mv res(a.size());
for(size_t i=0; i<a.size(); i++) res[i] = a.get(i) * scalar;
return res;
};
mv operator*(const mv& a, const double& scalar){
return scalar * a;
};