|
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