Boost logo

Boost :

From: Alan Griffiths (alan_at_[hidden])
Date: 1999-12-17 16:39:05

In message <>, 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

>> /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.

>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.

>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

Let me relate a problem from "real life"...

Cast: two "public" programmers Janet and John, and a library implementor

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

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

I think there is a problem here that is best addressed by modifying the

Alan Griffiths  (alan_at_[hidden])
ACCU Chairman   (chair_at_[hidden])   

Boost list run by bdawes at, gregod at, cpdaniel at, john at