Post by Ulrich EckhardtPost by tomIs there is a programmatic way to determine or detect within a []
operator method when the operator is being used for reading or
writing?
No.
1. You can overload the operator in a const and non-const version. For the
const version, you then return a const element which then can't be written
to. However, if you have a non-const [reference to a] container, it will
always call the non-const overload.
2. You can return a proxy object which features an assignment operator and a
conversion to the target type. When the assignment operator is called, it
is obviously being assigned to, otherwise only read. Note that you will
have to provide further operations like operator++ if you want "vec[idx]++"
to work.
Thanks. I have to explore your input as it relates to [] operators.
While the need was solved using specific access functions, I was able
to just solved it using get/put properties and this provided the same
collection like functionality I was looking for.
If interested, overall, I have a class (a parser) which creates CMap
collection of keys vs CArray strings.
typedef CArray<CString, const char *> TKeyList;
CMap<CString, const char *, TKeyList *, TKeyList *> Headers;
The keys can have duplicates, so the array is used to aggregate the
dupes using the using [] operator allowed for simple assignments:
CString & CMyClass::operator [](const char *s)
{
TKeyList *kl;
if (!Headers.Lookup(s, hl)) {
kl = new TKeyList;
Headers[s] = kl;
}
kl->SetSize(kl->GetSize()+1);
return (*kl)[hl->GetSize()-1];
}
So as you can see, this operator is only useful when building the
collection:
myclass["key1"] = string;
myclass["key3"] = string;
myclass["key3"] = string;
myclass["key1"] = string;
myclass["key2"] = string;
It wasn't designed for reading, so doing this:
last_string = myclass["key1"];
obviously would not work.
What I wanted to do is get the Last entry for a key which I resolved
using a specific GetLast(key) function.
But I used properties to give me the collection [] operator feel:
class CMyClass {
public:
...
CString &operator [](const char *s);
const char * GetLast(const char *szKey, const char *szdef = "");
..
private:
typedef CArray<CString, const char *> TKeyList;
CMap<CString, const char *, TKeyList *, TKeyList *> Headers;
};
const char *CMyClass::GetLast(const char *szKey,
const char *szdef)
{
TKeyList *hl = NULL;
if (Headers.Lookup(szHeader, hl)) {
if (hl->GetSize()) return hl->GetAt(hl->GetSize()-1);
return "";
}
return szdef;
}
class CApplet
{
private:
CMyClass myclass;
public:
_declspec(property(get=getPHeader,put=putPHeader))
CString Header;
virtual CString getPHeader(const char *szKey)
{
return myclass.GetLast(szKey);
}
virtual void putPHeader(const char *szKey, const char *szValue)
{
// assign using current CMyClass [] operator operator
myclass[szKey] = szValue;
}
}
---