|
Boost : |
From: Alisdair Meredith (alisdair.meredith_at_[hidden])
Date: 2003-08-05 10:50:06
David Abrahams wrote:
> Err, I don't get it. It seems to me that you only need the hack if
> you're going to *specialize* swap. *Using* std::swap should work just
> fine.
OK, that's because I was confused <g>
The following is really a minimal example, so I can be clearer this
time:
#include <boost/shared_ptr.hpp>
class empty
{
};
//#define DEMONSTRATE_BUG
# if defined( DEMONSTRATE_BUG )
namespace std
{
template<>
void swap( empty &lhs, empty &rhs )
{
}
}
# endif
int main(int argc, char* argv[])
{
boost::shared_ptr<int> pA( new int );
pA.reset();
return 0;
}
If we #define DEMONSTRATE_BUG the pA.reset() will cause:
[C++ Error] shared_ptr.hpp(286): E2285 Could not find a match for
'std::swap<>(int *,int *)'
Without the define, everything is fine.
This time it is clear that the swap specialization is nothing to do with
the shared_ptrs I want to swap. That was my misunderstanding. Creating
ANY specialization is going to trip up the borland parser.
The problem is that many boost libraries use std::swap. These are prone
to breaking the instant a user (or another of their library vendors)
makes the appropriate specialization.
The fix I am currently using looks like this in shared_ptr [line 284]
void swap(shared_ptr<T> & other) // never throws
{
#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x0564) )
_STL::swap(px, other.px);
#else
std::swap(px, other.px);
#endif
pn.swap(other.pn);
}
I am not submitting this as a diff yet as I am not sure this is the
'correct' patch yet, but I hope it gives the idea. A similar patch
needs to be applied everywhere in Boost std::swap is called, which could
be quite a bit of work. I am happy to go through all the libraries and
submit appropriate diffs, but first I would like agreement a patch is
appropriate, and the correct form.
The clear problems with my solution above are that
i/ the test is too wide (should be BCB >= 0x0560, AND using STLport, as
well as TESTED_AT) If this is going to be applied in many places I
suggest a new defect macro in borland config.
ii/ forcing _STL::swap means the library will not see the std::swap
specializations. This is not so much a problem when swap is specialized
as an optimization, but will be more of a problem for types that are
swappable but not copyable.
iii/ any other problems that I have missed.
I have not hit problems with any other standard library templates, but
in theory this could apply to any standard algorithm prone to
specialization, such as std::less.
-- AlisdairM
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk