|
Boost : |
From: Alan Griffiths (alan_at_[hidden])
Date: 1999-12-17 16:39:05
In message <714DFA46B9BBD0119CD000805FC1F53BDC394D_at_UKRUX002.rundc.uk.ori
gin-it.com>, Moore, Paul <Paul.Moore_at_[hidden]> writes
>From: Alan Griffiths [mailto:alan_at_[hidden]]
>> Three cases:
>
>[ I suppose I started this, so I'll jump in here]
>
>> /1/ Change name lookup rules so that boost::abs is found - without or
>> with "std::". (I think we agree this is wrong.)
>
>I'd agree this is wrong. If you explicitly ask for std::abs(), that's what
>you should get.
>
>> /2/ Require any client code that references an abs function in a class
>> where an abs member function exists to use a proxy function like:
>>
>> template<typename number_type>
>> number_type proxy_abs(number_type x)
>> { using std::abs; return abs(x); )
>>
>> (I guess this is what you intend. However, I think this would be a
>> maintenance disaster.)
>
>This is what I do (modulo compiler bugs) in the rational class. It is nasty,
>but I don't see it as a big issue. Then again, I don't view the rational
>class as "client" code - it's library code (as will be all generic stuff, in
>principle), and as such needs to take careful account of such issues.
No but rational<> should appear as much like a fundamental type as
possible to the eventual user. That user should be able to say
"std::abs(a_rational)".
[snip]
>
>> /3/ Allow std::abs to be overloaded on UDTs. (Maybe I've not seen the
>> problem with this approach - AFAICS the only issue is with
>> the letter of the standard.)
>
>I do think that allowing this seems innocuous (excepting any "purity of
>std::" issues).
I'm beginning to see problems - some std functions are impure (e.g.
scanf).
>But as long as users *can* put an abs() implementation in
>the UDT namespace, library designers *must* take care to cater for it.
I think we are addressing different issues here - unless the library
designer puts abs in std then the user is able to screw up by
specifically asking for the wrong one.
I think it is unfair to expect the user of your library to remember the
proxy function idiom.
>As
>such, the workaround in (2) above is still necessary (no, I won't let you
>say "my generic class only works if the template parameter's abs() function
>is defined in std::" :-) :-))
>
>So allowing this doesn't, in practice, gain the library designer anything.
>And user-level code shouldn't be worrying about this level of genericity
>anyway.
Let me relate a problem from "real life"...
Cast: two "public" programmers Janet and John, and a library implementor
(me).
Janet writes a class using std::vector<>, and provides a swap() method
and a free swap() function (as someone on this thread has already
described). She'd been paying attention during my seminar on exception
safety. The swap function looked something like:
C& C::swap(C& that)
{
using std::swap;
swap(a, that.a);
swap(b, that.b);
swap(c, that.c);
swap(d, that.d);
. . .
}
Some months later John comes along and decides that a container (call it
arg::vector) that I wrote would be better than std::vector. He changes
the class definition, re-runs the unit test harness and commits the
change.
The problem is, of course, that the resulting code /1/ no longer meets
the strong exception safety guarantee and /2/ is a lot slower. (I had
provided an efficient, non-throwing swap<> in namespace arg.)
Now I feel that I failed to provide a container that was sufficiently
like a standard container - I "rectified" this by partially specialising
std::swap (which I now realise was illegal).
If you provide a rational<> template that does not reflect the
"principle of least surprise" by behaving correctly when used with
std::abs then you too will be failing.
As the rules stand the problem is John's lack of knowledge. [John is
better than most - he has a strategy that avoids the problem in his own
code - writing a.swap(that.a) wherever possible]. But there are A LOT of
John's out there and I try to cater for them (and for myself on a bad
day).
I think there is a problem here that is best addressed by modifying the
rules.
-- Alan Griffiths (alan_at_[hidden]) http://www.octopull.demon.co.uk/ ACCU Chairman (chair_at_[hidden]) http://www.accu.org/
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk