Re: Perl style hash
On 10 Set, 11:57, Francesco <entul...@gmail.com> wrote:
On 10 Set, 10:15, Stuart Redmann <DerTop...@web.de> wrote:
On 10 Sep., 07:45, none <n...@none.none> wrote:
Sam wrote:
So? This calls for an overloaded Anything::operator=():
class Anything {
public:
// ..
Anything &operator=(double);
Anything &operator=(int);
Anything &operator=(std::string);
};
Okee-dokee.
And even if you could, you still wouldn't have the perl-style
behavior that I described. If you tried:
x["root"]["branch"]["leaf"] = 5;
the compiler would not know how to resolve the second (and third) =
set
of braces.
Of course it would. It's merely a matter of implementing operator[]=
()
accordingly.
I like the simplicity of this approach. The way I'm doing it now, =
I'll
have to add an iterator class to my wrapper, etc, which stinks. Yo=
ur way,
I'd just be using std::map directly.
But I still don't quite see how the second and third sets of [] would=
work.
The first one, x["root"], is going to return an Antyhing&. So, cla=
ss
Anything would have to also have a [] operator. How would the retu=
rned
Anything object access "x", which would be of type std::map?- Zitiert=
en Text ausblenden -
Try this:
#include <map>
#include <string>
#include <iostream>
#include <boost\any.hpp>
class CHashMapNode
{
private:
typedef std::map<std::string, CHashMapNode*> TNodeType;
TNodeType m_Node;
boost::any m_Value;
public:
CHashMapNode& operator[] (const char* KeyName)
{
// Look up the key in our map. If it doesn't exist, create one.
CHashMapNode*& NewNode = m_Node[std::string (KeyName)];
if (!NewNode)
NewNode = new CHashMapNode;
return *NewNode;
}
CHashMapNode& operator= (const boost::any& p_NewValue)
{
m_Value = p_NewValue;
return *this;
}
boost::any GetValue () const
{
return m_Value;
}
};
int main(int argc, char* argv[])
{
CHashMapNode HashMap;
HashMap["Root"]["Subnode"] = 3;
std::cout << boost::any_cast<int>
(HashMap["Root"]["Subnode"].GetValue ())=
;
HashMap["Root"]["Subnode"] = std::string ("Hello World");
std::cout << boost::any_cast<std::string>
(HashMap["Root"]["Subnode"].GetValue ())=
;
return 0;
}
Regards,
Stuart
Hi Stuart, hi everybody.
After having read the thread OP, I've started feeling dumb. I didn't
know how to implement a tree-like map (but now I see your example
above, Stuart) and I didn't know how to implement a "any_value"
object.
The first seemed impossible and I skipped it. I've started having a
try at the second, and here is my attempt:
-------
#include <iostream>
#include <map>
using namespace std;
class base {
public:
virtual string ti_name() const = 0;
virtual string Tti_name() const = 0;
virtual const void* get_data() const = 0;
virtual ~base() {}
};
template<class T> class variant : public base {
T data;
public:
variant(const T& t) : data(t) {}
const void* get_data() const {
return &data;
}
string ti_name() const {
static const type_info& ti = typeid(this);
return ti.name();
}
string Tti_name() const {
static const type_info& ti = typeid(T);
return ti.name();
}
};
class variantmap {
map<string, base*> datamap;
public:
class error {
public:
error(const string& s = ""): msg(s) {}
const string& what() {
return msg;
}
private:
string msg;
};
~variantmap() {
typedef map<string, base*>::iterator map_iter;
for (map_iter iter = datamap.begin(), end = datamap.end()=
;
iter != end;
++iter) {
delete iter->second;
}
}
template<class T> void write(const string& id, const T& t) {
if (datamap.find(id) != datamap.end()) {
delete datamap[id];
}
datamap[id] = new variant<T>(t);
}
template<class T> void read_in(const string& id, T* t) throw
(error) {
if (datamap.find(id) != datamap.end()) {
static const string& asked = typeid(T).name();
const string& saved = datamap[id]->Tti_name();
if (asked == saved) {
*t = *(static_cast<const T*>(datamap[id]->get_data(=
)));
} else {
throw error("Mismatch error:\n"
" map key == " + id +=
"\n" +
" value id == " + save=
d + "\n" +
" asked id == " + aske=
d + "\n");
}
} else {
throw error("Key error\n [" + id + "] not found\n");
}
}
};
int main()
{
variantmap vmap;
vmap.write("integer", 42);
try {
string s;
vmap.read_in("integer", &s);
cout << "s == " << s << endl;
} catch (variantmap::error e) {
cout << e.what();
}
try {
string s;
vmap.read_in("string", &s);
cout << "s == " << s << endl;
} catch (variantmap::error e) {
cout << e.what();
}
try {
int i;
vmap.read_in("integer", &i);
cout << "i == " << i << endl;
} catch (variantmap::error e) {
cout << e.what();
}
return 0;}
-------
I'll fiddle with it merging your tree-like map to my variant template,
Stuart.
@everybody: any suggestion, correction of bad approach, bug-fix or
comment about my code will be extremely welcome.
I've spotted one problem: if I let variantmap to be copied I'm in
trouble, have to define constructor, copy-constructor and assignment
operator to manage the dynamic memory.
Can you spot other problems there in my code?
Francesco