
David Abrahams wrote:
David Abrahams <dave@boost-consulting.com> writes:
So I'm wondering if there's a way to combine the advantages of your approach with those of mine.
The code in the sandbox now appears to be supporting both approaches. I've also added disable_if_same.
Use the BOOST_LVALUE_COPY_CTOR2 and BOOST_LVALUE_ASSIGN2 macros to ^ ^ auto-generate constructor/assignment overloads taking const_lvalue<T> instead of using the template technique. Let's call that "technique 2".
Findings --------
Aside from the easier time you'll have getting partial ordering of constructors and assignment operators with technique 2, I noticed the following:
The use of the 'explicit' keyword for a T const& ctor overload seems to be completely unneccessary. All the optimizations you can get in intel's strict mode are available using an ordinary non-explicit copy ctor. Am I missing something?
No, in some implementations you can just not provide the explicit constructor at all (at least gcc works well without it). If you do that you do not have the direct initialization problem anymore. I used the explicit keyword to use my approach with compliers like Comeau that do not like if you do not provide a X(X const &) constructor. I actually omitted to say this on the first iteration of the sample code because I though I needed to focus on the general approach. In the library I use with gcc I simply do not provide the explicit copy ctor at all.
In non-strict mode (and on Intel 8/win32) technique 2 seems to generate copies when constructing from const rvalues whereas technique 1 does not.
Yes, actually different compilers seem to act differently here. Since the compiler is free to copy const rvalues to non-const rvalues and optimize the copy away, I would consider returning a const temporary an odd thing to do. I am curious: does anyone have a use-case for it?
Not having a real T const& parameter for const lvalues makes writing overloads tricky. I was able to make the macros transparent for operator=, but because of initializer lists there's no way to do the same thing for constructors. const_lvalue<T> now has a conversion to T const&, so you can use boost::implicit_cast<T const&>(rhs) to get a reference to the argument with uniform syntax.
I am not sure I understood what you are saying here. Can you rephrase it please?
Results ------- [...]
We should probably try and not provide the explicit copy ctor with compilers that do not complain about it. I feel that this way some of the suboptimal copies will go away. Regards, Andrea Torsello