Boost logo

Boost :

Subject: [boost] use case of [move] rvalue reference emulation
From: DE (satan66613_at_[hidden])
Date: 2010-04-02 15:40:26


hi all
once i needed to pass around an object of a reference-like type
i.e. a class with reference semantics
something as trivial as

  template<typename type>
  struct ref
  {
    typedef typename type::value_type value_type;
    type &reference;
    const size_t index;

    ref(ref &a) : reference(a.reference), index(a.index) {}
    ref(type &a, size_t i) : reference(a), index(i) {}
    ref &operator=(const value_type &a)
    { /*setting value, e.g. 'reference.set(index, a)'*/ return *this; }
    operator value_type() const
    {/*return appropriate value, e.g. 'reference.at(index)'*/}
  };
  
so an access function returned an object of that ref type by value and
no function wanted to take it because eventually a rvalue could not be
bound to a non-const reference

then an idea of using a rvalue emulation proposed by boost move
library came in my mind
although it's not a move constructor it allows to construct objects of
type 'ref' from rvalues:

  ref(rv_ref<ref> &a) : reference(a.reference), index(a.index) {}

and also a conversion to rv_ref sholud be added:

  operator rv_ref<ref>&()
  { return *static_cast<rv_ref<ref>*>(this); }

see fully working code example at http://codepad.org/rRM93AFo

defining a reference type "rvalue copy assignable" makes it behave
almost the same as ordinary c++ references
also constness is preserved perfectly
and it happend so that all limitations of the emulation only
strengthen the design of such reference types (e.g. unavailability of
'type(const type&)' constructor)

an example of the application of such reference types may be an
advanced map class
when you subscript an stl map object like

  map[key];

a record with the 'key' is created in the map if it's not there
already
so not to overpopulate our map we write something like

  value_type value;
  if (map.is_there(key))
    value = map[key];

of course there is no such 'is_there()' member function in an stl map
i'm just trying to make my intention clear

so were that smart reference typedefed in the map like

  template</*...*/>
  class map
  {
  public:
    //...
    typedef map_ref<map> reference;
    //...
  };

it could have slightly better semantics:

  map[key]; //always does nothing
  map[key] = new_value; //if there is no record with 'key' -> creates it
                         //assignes 'new_value' to the value of the record
  value = map[key]; //retrieves a value associated to 'key'

in the last case if there is no such record in the map it may return
an invalid value or throw an exception
anyway i consider this semantics more natural than that of the current
std::map

not to mention that you may pass a reference to a function:

  void foo(map::reference a)
  { a = "42"; } //if there was no record -> creates it
  //...
  foo(map[key]); //does not create record at this point

and it will work flawlessly

-- 
Pavel
P.S.
if you notice a grammar mistake or weird phrasing in my message
please point it out

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