Boost logo

Boost :

From: Andrea Torsello (torsello_at_[hidden])
Date: 2004-04-19 10:19:26


David Abrahams wrote:

> Andrea Torsello <torsello_at_[hidden]> writes:
>
>> Sorry for the late reply: I have been away on Sunday. By the way,
>> you guys are amazing:
>
> I'm doubly flattered to be "pluralized" in that way! BTW, the message
> you're replying to is a pretty old message in the scheme of things;
> I've moved past much of what I said there.

Well, I couldn't be sure it was just you, so I erred on the side of
caution...

>
> I've been trying to convince the EDG guys that it's "obvious" that
> *if* you absolutely must choose between direct and copy initialization
> for the RVO, the intuitive choice is to go for direct initialization,
> because, well, it's "direct". That's the user perspective. The point
> is that from the point-of-view of a standards wonk and compiler
> implementor, there's no particular reason to think that RVO is easier
> in the direct case than in the other one.

I ment that the recieiving side is easyer that the returning side: it is
harder to make sure that a function that returns a temporary does not make
a copy than it is to make sure that a direct or assignment constructor is
elided when passed a temporary. From a user perspective, the choice of
copy-initialization (direct or assignmetn) should make no difference to
RVO, no matter what language lawyers say about it.

>
>> As for the syntactic overhead, I believe that my approach has an
>> edge here, since it minimizes the amount of adjustments the user
>> has to go through in order to use it, but of course this is a
>> matter of personal opinion and I am certainly biased ;)
>
> I think you have a good point, actually. The two approaches each have
> their own strengths apparently, and I'm less convinced of the
> advantages of technique 1 than I used to be. OTOH, I'm not convinced
> there's any advantage at all to using an explicit copy ctor.

As your tests point out, technique #1 might force less moves with compilers
that are not too aggressive when optimizing. I wonder if the two approaches
should coexist, at least for a while and let the users choose between
syntactic semplicity and (possibly) higher efficiency.

> Maybe a nicer enabler should be provided, that allows us to write:
>
> typename enable_lvalue<T, X, void>::type // no "const"
>
> The enablers get more interesting if you want to write a generic
> function over a templated type Y<U>:
>
> template <class T>
> typename enable_if<is_Y<T>,void>::type
> f(T& x);
>
> fortunately I have macros to generate is_Y (see
> boost/python/detail/is_xxx.hpp). On the other hand, with technique 2
> I think you can't write the generic function at all, because template
> arguments have to match exactly:
>
> template <class T>
> void f(const_lvalue<Y<T> > x); // can never match a Y<T> argument

Right. That is why in my test code I had to explicitly qualify
disctiminate<int>
I wonder whether we can do something similar with technique #2... Something
else I should look into.
 
> I think you're possibly suggesting what I did in the example above?
> I must've misinterpreted you because technically there's no overload
> there.

Exactly.

 
> Let's see, would you want a shared_ptr<Derived> to be _IMPLICITLY_
> convertible to a shared_ptr<Base>? ;-) Seriously, most such
> converting ctors I've seen in the wild are of that nature. I don't
> think there's any way to generalize about whether explicit is usually
> needed.

Point taken. Different backgrounds, different use-cases in mind.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk