
Daniel Wallin <dalwan01@student.umu.se> writes:
David Abrahams wrote:
Daniel Wallin <dalwan01@student.umu.se> 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