From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2006-05-11 07:27:44
Andras Erdei wrote:
> On 5/9/06, Tobias Schwinger <tschwinger_at_[hidden]> wrote:
>>>Do you already have possible overloads and return types for convert() in
>>Sure: 'convert' returns an expression, just like any other operator. That
>>expression will be something like a reference wrapper for the argument.
>>When the full compound expression is evaluated the convert expression
>>protects its component expression from result type propagation.
>>Best case, it's all it does -- the evaluation machinery can view the
>>result of the evaluation as a value of the expected domain.
> void f( rational const & ) ;
> void f( integer const & ) ;
> integer a , b ;
> f( convert( a ) / b ) ;
> what is going to happen ?
Overload resolution is ambiguous. And it makes perfect sense: an expression (talking pen-and-paper math) without a target domain is just an expression...
> or do you expect end-users to provide overloads like
> void f( integer_expression_stub const & ) ; ?
> then they are bound to a particular implementation of integer.
No - use a template. This way the expression can be used for further optimization within the algorithm.
Note that the most efficient usage has the simplest interface.
> am i missing something?
My explanation is certainly still missing one important case to be complete: what if you need a separate translation unit?
Well, I propose a function template - let's call it 'promote' - that enforces to the worst case domain within the expression.
f( promote(convert(a) / b) ) // constructs a temporary of b's domain
. An explicit conversion would work as well...
Note that unlike with converting constructors, here is no (maybe costworthy) magic behind the scenes -- the user has to explicitly request an operation, which is in fact a good thing.
As a library developer you can, of course, put the invocation of 'promote' into an inline function template
in your header to enable implicit promotion.
> i am also not convinced the proposed evaluation mechanism is really useful:
> it may look better than
> rational r = rdiv(a , b) ;
To come anywhere remotely close, performance-wise (and without expression templates) it would have to be:
Which is not arguable to be inconvenient.
Further we would need manifold overloads (on a per-argument basis) that essentially do the same thing but for different input domains -- a maintainance nightmare on the implementor's side.
To be equally efficient we would finally need variants for some input arguments to be destructible (we can't use overloading so it makes the interface even uglier).
All construction of temporaries would be spelled out by the user and clutter problem-specific code with manual optimization -- a maintainance nightmare on the client's side.
> to some, but looks worse for others,
Now, after "correcting" the equivalent non-ET interface I find it hard to imagine that there's a single soul on this planet who seriously prefers it...
> and it goes against existing practice;
Well, AFAIK math *is* existing practice. In fact, it has even been there first!
> but maybe i'm just too conservative
Careful comparison with more conservative approaches is required to find out whether a new way is superior or not...
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk