Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-05-09 12:40:52


Daniel Wallin <dalwan01_at_[hidden]> writes:

> David Abrahams wrote:
>> Daniel Wallin <dalwan01_at_[hidden]> writes:
>>
>>
>>>David Abrahams wrote:
>>>[...]
>>>
>>>>The question is, what should we do about this? It turns out to be
>>>>surprisingly hard to write the declarations of these temporary
>>>>variables so they work in all cases. For example, v had to be a
>>>>const& because in one case index_result<...>::type turned out to be
>>>>
>>>> char const[4]
>>>>
>>>>and when the default is used, it's
>>>>
>>>> double
>>>>
>>>>with p[value || ...] returning a double rvalue (by value).
>>>>
>>>>Thoughts?
>>>
>>>Make the user add reference to the Default type instead of
>>>index_result<>::type?
>>
>>
>> I don't fully understand what you're proposing or what it's supposed
>> to address, but I think you might be missing the point. To make it
>> safe to use, ideally
>>
>> index_result<...>::type whatever = p[x | some-expression];
>>
>> would always cause a by-value return from p[...] when some-expression
>> is an rvalue.
>
> It's perfectly safe for p[...] to always return by reference, even if
> some-expression is an rvalue. The only problem is that it's hard for the
> user to determine if the result should be held by reference or not.

OK, that's one way to look at it: it's perfectly safe for the library
to do X, as long as the user is really careful to do Y when necessary.
I was looking at this from the user's eyes: she'd like the library to
do something that's always safe and never require her to "determine if
the result should be held by reference or not."

> I propose that the user tells index_result<> if the result of the
> default expression should be by reference, so that:
>
> index_result<.., int>::type whatever = p[x | 0];
>
> whatever stores a copy of 0 in the default-case, and stores a reference
> to p[x] otherwise.
>
> int default_ = ...;
> index_result<.., int const&>::type whatever = p[x | default_];
>
> See what I'm saying now? Am I missing the point?

That's not too bad.

I think we might be able to make it a bit safer by detecting when the
default is a non-const rvalue and having p[...] return by value in
that case. However, that might come at the cost of some efficiency if
the user also happens to use a non-reference variable:

  index_result<.., heavyweight_type>::type = p[x | rvalue_expr() ]

Of course, when it's heavy the user will probably be using || for lazy
defaults, in which case, can we protect her?

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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