Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!microsoft!jimad From: jimad@microsoft.UUCP (Jim ADCOCK) Newsgroups: comp.lang.c++ Subject: Re: operator []: ref vs value Message-ID: <51111@microsoft.UUCP> Date: 28 Feb 90 19:28:12 GMT References: <5216@brazos.Rice.edu> Reply-To: jimad@microsoft.UUCP (Jim ADCOCK) Organization: Microsoft Corp., Redmond WA Lines: 101 /**** You can't make two versions of op[] for lvalue and rvalue, but you can differentiate the situations where an op[] is taken, and where an op[] is taken and value is changed. The general trick is for op[] to return a smart proxy for that element, and a special assignment to the proxy is defined that updates the vector if the value of the proxy, [and thus the element] changes. Just to confuse things, in the below sketchy example, I use the same class "SVEL" for both the elements of the vector, and the proxy to that element. ****/ class SVEL// a sparse vector element { SVEL* psvel; class SV& sv; int i; double d; public: SVEL(SV& svT, int iT, SVEL* psvelT, double dT=0.0); SVEL(SV& svT, int iT); SVEL& operator=(double d); void Attach(SVEL* psvelT) { psvel = psvelT; } SVEL* Next() { return psvel; } int Index() { return i; } void Print(); operator double() { return d; } }; SVEL::SVEL(SV& svT, int iT, SVEL* psvelT, double dT) : sv(svT), i(iT), psvel(psvelT), d(dT) {} SVEL::SVEL(SV& svT, int iT) : sv(svT), i(iT), psvel(0), d(0) {} void SVEL::Print() { printf("(%d, ",i); printf("%g) ",d); } class SV // a sparse vector { SVEL* psvel; public: SV(); void Attach(SVEL* psvelT) { SVEL* pT = psvel; psvel = psvelT; psvel->Attach(pT); } SVEL& operator[](int i); void Print(); }; SV::SV() : psvel(0) {} SVEL& SVEL::operator=(double dT) { if ((d==0.0) && (dT!=0.0)) { d = dT; sv.Attach(this); } else d = dT; return *this; } void SV::Print() { SVEL* p = psvel; while (p) { p->Print(); p = p->Next(); } putchar('\n'); } SVEL& SV::operator[](int i) { SVEL* p = psvel; while (p && (i != p->Index())) p = p->Next(); if (p) return *p; else return *new SVEL(*this, i); } int main() { SV v1, v2; v1[100] = 10.0; v1[200] = 20.0; v2[10] = v1[1]; v2[20] = v1[200]; v2[30] = 300.0; v1.Print(); v2.Print(); v2[20] = 200.0; v2.Print(); double d20 = v2[20]; printf("%g\n", d20); return 0; } // gc left as an exercise :-)