Boost logo

Boost :

From: Ulrich Eckhardt (uli_at_[hidden])
Date: 2004-12-30 07:30:32


I had the idea to use boost::optional on the interface of a std::map-like
object. I have neither coded a prototype nor is this a fully grown design
yet, I'd just like to discuss this idea.

The rough outline is this:

class my_map
{
public:
    optional<value>& operator[](key const&);
    optional<value> const& operator[](key const&) const;
    // iterators, ctors, dtor, etc the same
private:
    optional<value> const m_empty_value;
    tree< pair<key, optional<value> > > m_content;
};

The important differences to std::map are:
1. operator[] is available as const and non-const memberfunction. The const
memberfunction returns 'm_empty_value' in case the key is not found. The
non-const one inserts a new node into the tree and returns a reference to
that.
2. operator[] return an optional<value>, not a direct value. This means that
you have to check the return-value of this call. OTOH, you _can_ check the
return value to see if a key was associated with a value.

Some example code, compared with the equivalents using std::map:

// two maps
std::map<string,float> stdmap;
my_map<string,float> mymap;
// const references, for cases where it makes a difference
std::map<string,float> const& stdmapc = stdmap;
my_map<string,float> const& mymapc = mymap;

///////// inserting an element:
stdmap["key"] = 41.0f;

mymap["key"].reset(42.0f);

///////// accessing an element
access(stdmap["key"]);

std::map<string,float>::const_iterator it = stdmapc.find("key");
if(it!=stdmapc.end())
    access(it->second);
else
    access(float());

boost::optional<float>& value = mymap["key"];
if(value)
    access(*value);
else
    access(float());

boost::optional<float> const& value = mymap["key"];
if(value)
    access(*value);
else
    access(float());

///////// removing an element
stdmap.erase("key");

mymap["key"].reset();

///////// finding out if an element exists
if(stdmap.find("key") != stdmap.end())
    found();

if(mymap["key"])
    found();

///////// iterating and accessing
for(std::map<string,float>::const_iterator it=stdmap.begin();
    it!=stdmap.end();
    ++it)
    access(it->second);

for(my_map<string,float>::const_iterator it=mymap.begin();
    it!=mymap.end();
    ++it)
    if(it->second)
        access(*(it->second));


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk