Я хочу создать коллекцию классов, которые ведут себя как математические векторы, так что умножение объекта на скаляр умножает каждое поле на эту сумму и т. Д. Дело в том, что я хочу, чтобы поля имели реальные имена, а не рассматривается как индекс.
Моей первоначальной идеей для реализации этого было создание базового класса Rn с перегрузками, а затем создание производных классов с красивыми именами. Примерно так:
#include <iostream>
#include <algorithm>
using namespace std;
template<int N, class X=double>
struct Base{
X xs[N];
Base(){};
Base(X *data){
copy(data, data+N, xs);
}
Base operator*= (double d){
for(int i=0; i<N; i++){
xs[i] *= d;
}
return *this;
}
Base operator* (double d){
Base answer = *this;
answer *= d;
return answer;
}
//also operators for +=, +, multiplication from left, maybe [] too
};
struct Derived : public Base<2>{
Derived(double a, double b){
foo() = a;
bar() = b;
}
double &foo(){ return xs[0]; }
double &bar(){ return xs[1]; }
};
int main()
{
//this is OK:
double data[2] = {0.0, 2.0};
Base<2> b(data);
b = b*17.0;
cout << b.xs[0] << endl;
//I can't do this:
Derived x(0.0, 2.0);
x = x*17.0;
cout << x.foo() << endl;
return 0;
}
Я получаю ошибку компилятора всякий раз, когда пытаюсь использовать операторы, требующие копирования.
gcc дал мне следующую ошибку компилятора:
teste.cpp: In function ‘int main()’:
teste.cpp:52: error: no match for ‘operator=’ in ‘x = x.Derived::<anonymous>.Base<N, X>::operator* [with int N = 2, X = double](1.7e+1)’
teste.cpp:31: note: candidates are: Derived& Derived::operator=(const Derived&)
Мне кажется, проблема в том, что функции перегрузки имеют дело с объектами Base, которые не могут быть преобразованы в производные, поэтому я не могу использовать их в производном классе. Однако я не могу придумать решение. Есть ли способ обойти это или я должен использовать совершенно другой подход?
Дополнительный вопрос: есть ли способ, с помощью которого я могу использовать std :: valarray, чтобы избежать необходимости набирать много и много перегрузок операторов?