Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Language
English











SourceForge.net Logo

Transfer semantics

Explicit pick/clone

U++ containers require the transfer mode (deep copy or move) to be explicitly specified when transfering the content of the container, except the case . This decision has the advantage of not accidentally using costly deep copy semantics, when in reality move is required in majority of case. Moreover, for the increased safety, the source after moving is considered to be in "picked" state and number of operations that can be performed on it is limited. In most cases, only allowed operations here are operator=, destructor and Clear. This one of reasons for having 'pick' function (and using term 'pick' instead of 'move', even if the semantics is about the same as 'std::move'.

Vector<int> a, b;

a = pick(b); // moves content of b to a, b is put into picked state

b = clone(a); // a and b now contain the same data

C++03 compatibility

In ideal world, we would be now using only C++11. In real world, we will need to support C++03 for forseeable future.

pick constructor/operator= in C++11 can obviously use

T(T&&);

T& operator=(T&&);

forms. However, to support C++03, we need to implement them using quite ugly trick as

T(T const&);

T& operator=(T const&);

because not doing so would break returning values from functions, as temporaries in C++11 can only be bind to constant references. To hide this difference, we

#define rval_ &&

in C++11 and

#define rval_ const&

in C++03 to get unified the form

T(T rval_);

T& operator=(T rval_);

(parameter then also has to be const_casted, but that is not a problem in C++11). Note also that semantics of 'pick', for this reason, is not tested very well in C++03.

Composition

When class contains members with pick semantics, a lot of error-prone work is saved when compiler is able to generate pick constructor/operator= for the class. C++11 is quite capable of doing so, but often needs to explicitly activate it with default memebers:

Foo(Foo&&) = default;

Foo& operator=(Foo&&) = default;

Meanwhile, C++03 does need these and does not recognize them. To make things easier, we define macro rval_default, which simplifies this and irons out differences

rval_default(Foo)

Optional deep copy - clone, uniform access to deep copy

To support clone, class has to define special constructor of form

T(const T&, int)

and to derive from DeepCopyOption<T> class, which provides support for static/dynamic construction of instances.

Changing default semantics

If for some reason you need version of optional deep copy type with default deep copy, you can easily create it with WithDeepCopy template

IntArray a = MakeArray(100);

WithDeepCopy<IntArray> b(a); // b now has deep copy semantics

a[3] = 10; //legal

b = a; // deep copy

a = b; // pick

b[4] = 1; // illegal

 

Last edit by cxl on 11/04/2014. Do you want to contribute?. T++