
"Andrea Torsello" <torsello@dsi.unive.it> writes:
Correct me if I am wrong, but if both behaviour could be interpreted as correct based on the current standard, it means that relying on one interpretation is undefine behaviour. At least untill a TC is issued.
Well, it's not undefined behavior. At best it's unspecified. IMO with a careful reading of the standard, the interpretation taken by Comeau is just wrong. What the standard says is really irrelevant, though. What matters are the status quo today and what will happen in the future. Today, compilers all act differently. In the future we have the assurance of the CWG that my move example from N1610 will work, via one of several possible routes. By the way, if you are willing to give up on move semantics from direct initialization, my technique will work in Comeau strict mode just as well as yours. Nothing about what you did will get around that problem; it seems to be a fact of current EDG compilers that in strict mode direct initialization from an rvalue will only ever use an ordinary (T const&) copy ctor. The current version in the sandbox turns off the move optimization for that case on current EDG in non-microsoft mode. If you're not compiling in strict mode you can turn it back on with -DBOOST_IMPLICIT_MOVE_CTOR_FOR_COPYABLE_TYPES. In fact, compilers in general are good enough at copy elision that the move ctor optimization only turns out to be useful for one other compiler I can find: Intel 8.0 for Windows, where it works silently and is enabled by default. I haven't tried /Za mode but apparently that's useless for building real software on Windows.
Besides it is not the only problem. I didn't just start to create my own version for pleasure. I started using your approach but the templated constructor had weird interactions with other 2 parameter constructors. I cannot remember the case off hand, but I will look for it and post it.
Please do. Also please use the latest version of the code in the sandbox to test against.
There is never a need to pass a temporary by const ref if you can move it.
What if the user of the library wants to pass the object to a function that has that signature? One of the main goal is for the move infrastructure to be as transparent as possible.
I'm sorry I was unclear. My library allows you to pass a temporary by const ref transparently. You said:
Finally the need for X(X const &) to pass a temporary by const ref was the reason that forced Alexandrescu to add the special return type to mojo.
Actually I'm not sure what I was trying to say anymore. I can state that my library already allows sink(source()); to work transparently with move semantics on all compilers I've tested on.
Yes. template <class T> enable_if_same<T const, X const, void> f(T&); // lvalues void f(move_from<X>); // temporaries
Right, didn't realize that you could use the same trick here, good stuff! Anyway, using enable_if_same as a result type convertible to the required type
Sorry, that wans just a mistake; it isn't convertible to anything. I meant: template <class T> // lvalues typename enable_if_same<T const, X const, void>::type f(T&); void f(move_from<X>); // temporaries
Anyway forcing an otherwise non-templated fiunction to be templated, while not a real problem is not really optimal, especially considering the difficulty most compilers have with the export keyword. Of corse, the templated class might just delegate all work to a non templated class
Exactly. Or you could just use explicit instantiation. BTW I assume you mean "templated function".
, but still.
It's no worse a problem than replacing what should be a reference paramter with another type that can be constructed by implicit conversion. You still cut off the possibility of user-defined conversions.
The code snipped you sent on the quoted message doesn't appear to allow it, but as I said, I am not sure about newer versions.
Why don't you do some research? It's all in the sandbox.
I did
I meant "research into newer versions". If you had done that, you could be sure of it. If you run the latest tests with --verbose-test on the bjam command-line, it will show you exactly what's allowed and how many unneccessary copies are made with your compiler.
, and I proposed an alternative which has some advantages and some disadvantages.
I don't see any advantages yet.
If you like i,t please use it, if you don't, don't! I was looking for feedback and constructive criticism, not forcing my approach to anyone.
I didn't take it that way. I'm not arguing with you out of defensiveness. If you really think what you did had some advantages, I want to be convinced of them so I can change my library to be the best possible.
I still don't understand why you think it's important to distinguish const temporaries from const lvalues.
As you said in another post, it is not a problem to move from a const temporary (the compiler might just copy the const temporary to a non const temporary and optimize the copy away), hece you want to move from const temporaries.
Which my library does.
On the other hand, you should certainly not move from lvalues.
OK, but in that case I don't see why you want to distinguish const temporaries from non-const temporaries. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com