Здравствуйте, VladD2, Вы писали:
FR>>>>На C++ шаблонах такое пишется без проблем, используются ленивые вычиления, то есть выражение собирается в operator= скорость не уступает сишной.
VD>>>Решение конечно на шаблонах с применением Буста?
FR>>На шаблонах без буста. Я такой велосипед писал когда про буст еще не слышал.
VD>Дык, изобрази... посмеемся вместе.
Вот очень грубый эскиз
// исходный контейнер
struct vector
{
int size() const;
double operator[](int) const;
double& at(int);
template<class V> operator=(const V& v)
{
for(int i=0, n=size(); i!=n; ++i)
at(i) = v[i];
}
};
// ленивая арифметика: кирпичики
template<class V> struct vmul_t
{
const V& v; double m;
vmul_t(const V& v, double m) : v(v), m(m) {}
double operator[](int i) const { return v[i]*m; }
};
template<class V>
vmul_t<V>
vmul(const V& v, double m) { return vmul_t<V>(v,m); }
template<class V1, class V2> struct vsum_t
{
const V1& v1; const V2& v2;
vsum_t(const V1& v1, const V2& v2) : v1(v1), v2(v2) {}
double operator[](int i) const { return v1[i]+v2[i]; }
};
template<class V1, class V2>
vsum_t<V1,V2>
vsum(const V1& v1, const V2& v2) { return vsum_t<V1,V2>(v1,v2); }
// обёртка над кирпичиками позволяет избежать комбинаторного взрыва
template<class V> struct vid_t
{
const V& v;
vid_t(const V& v) : v(v) {}
double operator[](int i) const { return v[i]; }
};
template<class V>
vid_t<V>
vid(const V& v) { return vid_t<V>(v); }
// строим выражения: сперва с участием конкретных типов слева (вектор, число)
template<class V>
vid_t<vmul_t<V> >
operator* (double m, const V& v) { return vid(vmul(v,m)); }
vid_t<vmul_t<vector> >
operator* (const vector& v, double m) { return vid(vmul(v,m)); }
vid_t<vmul_t<vector> >
operator/ (const vector& v, double m) { return vid(vmul(v,1/m)); }
template<class V2>
vid_t<vsum_t<vector,V2> >
operator+ (const vector& v1, const V2& v2) { return vid(vsum(v1,v2)); }
template<class V2>
vid_t<vsum_t<vector,vmul_t<V2> > >
operator- (const vector& v1, const V2& v2) { return vid(vsum(v1,vmul(v2,-1))); }
// а теперь слева шаблон vid_t
template<class V>
vid_t<vmul_t<V> >
operator* (const vid_t<V>& v, double m) { return vid(vmul(v,m)); }
template<class V>
vid_t<vmul_t<V> >
operator/ (const vid_t<V>& v, double m) { return vid(vmul(v,1/m)); }
template<class V1, class V2>
vid_t<vsum_t<V1,V2> >
operator+ (const vid_t<V>& v1, const V2& v2) { return vid(vsum(v1,v2)); }
template<class V1, class V2>
vid_t<vsum_t<V1,vmul_t<V2> > >
operator- (const vid_t<V>& v1, const V2& v2) { return vid(vsum(v1,vmul(v2,-1))); }
Здесь можно добавить следующие вещи:
1) избавиться от лишней косвенности (т.е. снимать обёртку)
template<class V> struct clean_t { typedef V type; };
template<class V> struct clean_t<vid_t<V> > { typedef V type; };
template<class V> const V& clean(const V& v) { return v; }
template<class V> const V& clean(const vid_t<V>& v) { return v.v; }
// и пропатчить все операторы вот так:
template<class V1, class V2>
vid_t<vsum_t<typename clean_t<V1>::type, typename clean_t<V2>::type> >
operator+ (const vid_t<V>& v1, const V2& v2) { return vid(vsum(clean(v1), clean(v2)); }
2) протащить через выражения не только operator[], но и функцию size()
3) сделать нормальное деление и вычитание вместо эмуляции на сложении и умножении
и т.д. и т.п.
... << RSDN@Home 1.2.0 alpha rev. 655>>