我想创建一个类似于数学向量的类的集合,因此将对象乘以标量将每个字段乘以该ammount等等。事情是我希望字段具有实际名称,而不是被视为指数。
我实现这个的最初想法是创建一个带有重载的基类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来避免输入大量的操作符重载?
答案 0 :(得分:3)
您的Base运算符(在本例中为*)可以接受Derived对象,但它们返回Base,不能在Derived default assignment operator中用作右侧操作数。解决此问题的最简单方法是向Derive添加一个赋值运算符,它将采用Base:
Derived& operator= (const Base<2>& other)
您必须将它添加到任何派生类,但实现相当简单(您可以在Base中使用void CopyOtherBase函数来执行复制,并让所有operator =调用它并返回* this)。 / p>
答案 1 :(得分:2)
我只会解决技术难题,而不是这是否是个好主意。
问题是Derived的operator *的结果是Base,而且operator = Derived(默认运算符=)不知道如何“吃掉”Base。
一个简单的解决方案是创建Derived的构造函数,该构造函数获取Base,并执行正确初始化所需的任何操作。这将允许将Base实时转换为Derived - 并且适用于期望Base的所有其他Derived运算符。
有些事情 -
Derived(const Base<2>& B) : Base<2>( B )
{
}
答案 2 :(得分:1)
我认为使用枚举或静态常量来命名字段会好得多
例如,static const int FIELD_NAME = 0;
静态const int FIELD_NAME2 = 1;
比不同类型(模板)这样做。然后你可以使用std :: valarray或boost :: ublas :: vector / matrix类型来利用现有代码&amp;获得质量性能矢量操作来启动。
答案 3 :(得分:0)
模板元编程有一个有趣的想法,用数学向量解决这类问题,但可能无法解决你命名部分的问题。
David Abrahams,Aleksey Gurtovoy:C ++模板元编程:来自Boost and Beyond的概念,工具和技术,Addison-Wesley,ISBN 0-321-22725-5
答案 4 :(得分:0)