On Tue, 27 Jan 2009 01:52:26 +0300, Steven Schveighoffer <[email protected]> 
wrote:

"Andrei Alexandrescu" wrote
Steven Schveighoffer wrote:
I guess I'm not really sure what the "acquire" method does.  I saw you
mention it in another post, but with no explanation as to what it
actually does, just that it was needed.  I'm sure I'm not getting what
should be obvious, but if you could enlighten, I would appreciate it :)

Say you have an object obj that has a Matrix property and you have a
Matrix object handy. The Matrix is rather resource intensive so you'd
rather not copy it unwittingly. Conventionally, if you say:

Matrix m;
... fill matrix ...
obj.matrix = m;

then m is copied into obj.matrix (there is the by-value call to set
property). Now it's possible to arrange things such that m is
destructively copied, but as the auto_ptr disaster has shown, it's not
that intuitive to make assignment destroy the right hand side.

So we'd need a distinct method:

obj.matrix.acquire(m);

That method takes the matrix by reference, sucks its life out of it, and
leaves an empty shell behind. Pretty much like in your average horror
movie.

So what you are saying is that you want to control the set such that it
destroys the source (essentially, I'm reading, you don't want to do a deep
copy, just a reference copy, and then null the original reference).

Let me ask another question then... does a property have reason to have both set AND acquire? More specifically, does a function that takes a property as an argument as we have been discussing need both set and acquire passed to it? If not, you can simply pass the set method that you want, still only requiring a pair of functions. How to signal that to the compiler easily? Not so sure... but it does seem to me like a type should know how it should
be copied, and likely doing it other ways should require special methods.

I can think of possible library solutions to this, say a wrapper property
struct that can call any two functions to do set or get.


Having the two functions seems like a reasonable baggage compromise, if
you want to control the get and set methods of a property and pass that
control to an underlying function, you need at least that.  If we start
generalizing it to anything, then it starts looking like struct
interfaces would be more suitable. For example, you could allow setting an int property using both an int and a string, do you want to pass both
setters to a function?  I think limiting it to just a set and a get
function should be sufficient.

With only get and set I can't implement a nothrow swap, which kinda bends
me out of shape.

Sorry, don't get that either.  Why can't set and get be used in a nothrow
swap?

-Steve



Because set implies data copying (read: allocation) and copy constructor call, 
both of which can throw.

How about the following - you call a swap with a dot syntax:

int x = 42;
int y = 13;

x.swap(y); // calls global void swap(T)(ref T, ref T); or a specialized 
version, swap(ref int, ref int);

User is, however, free to implement his own swap method:

struct BigInt
{
   ...
   void swap(ref BigInt other) { ... }
   ...
}

Or another way - "void swap(T)(ref T lhs, ref T rhs);" tries "lhs.swap(rhs);" first, and 
falls back to "auto tmp = lhs; lhs = rhs; rhs = tmp;" if no lhs.swap method is defined.
This way you can define "void aquire(ref T newOwner, ref T data);" as 
"newOwner.aquire(data);" and fall back to "swap(newOwner, data); release(data);" on 
failure.
"void release(ref T obj);" tries "obj.release();" first and falls back to "swap(obj, 
T());" or "obj = T();" on failure.


Reply via email to