Pointer to member object operator

Started by
10 comments, last by ToohrVyk 16 years, 8 months ago
Thanks guys for the responses - most helpful. The "additional functionality" is something like this..... I'm dealing with very large multi-dimensional data sets (1024x1024x4 of bytes/ints/floats) but luckily I know most of the array will be empty which means std::map is perfect. *Except* all my code so far is based around a managed (dense) array of floats (the bptr type notation). std::map already provides an overloaded [] operator which could do the job.... almost. As I understand in std::map *creates* a new key/data pair if you call [] with a key which is not already in the map. What I want to do is have the [] operator act as usual if the key is in the map but if the key is not in the map I want zero (0.0f) to be returned with no extra objects created. If I use std::map as is my memory will max out super fast. By wrapping up std::map I thought I could do the check for the key and then return whatever based on if the key exists or not.

From a design point of view perhaps what I'm doing isn't the greatest but
a) there's an awful lot of code that uses the existing array directly
b) I couldn't think of anything else ;) (not a very good reason I know!)

Things are also made slightly more involved because the class actually wraps an implementation class to allow the data type stored in bptr to "dynamically" change type (see my earlier post about this).
Advertisement
Quote:Original post by coordz
What I want to do is have the [] operator act as usual if the key is in the map but if the key is not in the map I want zero (0.0f) to be returned with no extra objects created. If I use std::map as is my memory will max out super fast. By wrapping up std::map I thought I could do the check for the key and then return whatever based on if the key exists or not.


You will run into problems with this (the same problem as me, see this thread). The reason is that the user will want to use b = x; to set the value at index i to x—so, you'd have to return a reference.

A solution which I could not afford, but you may find interesting, is to restrict the ways in which contents can be manipulated. Fundamentally, you would have operator[] return the following class:
template<typename key_t, typename value_t>class reference_type{  public:  typedef key_t key_type;  typedef value_t value_type;  typedef std::map<key_type,value_type> assoc_type;  typedef reference_type<key_type,value_type> self_type;  // Determines if map contains the element, returns  // it if it does, return the default value otherwise.  operator const value_type &() const {     assoc_type::iterator it = assoc.find(key);    if (it == assoc.end()) return default_value;    else return it->second;  }  // Inserts the new value into the map (or modifies  // it in place if it's already inside)  self_type & operator=(const value_type & v) {    assoc[key] = v;    return *this;  }  // Possibly add overloads for +=, -=, *=, /=, ++, --  // Construct  reference_type(assoc_type & assoc,                  const key_type & key) :    assoc(assoc), key(key)   {}private:  assoc_type & assoc;  key_type key;  value_type default_value;};template<typename key_t,value_t>class Sparse {  typedef key_t key_type;  typedef value_t value_type;  typedef reference_type<key_type,value_type> reference_type;  typedef std::map<key_type,value_type> assoc_type;  reference_type operator[](const key_type & k) {    return reference_type(this->assoc,k);  }private:  assoc_type assoc;}


This topic is closed to new replies.

Advertisement