
David Abrahams wrote:
How to solve this problem is not a mystery. We just had a long thread about it entitled "[range] How to extend Boost.Range?" Have you completely missed it?
I haven't followed it.
I am getting frustrated here because it seems to me that you haven't done your homework,
That's why I asked for more time to consider the issue - but you couldn't accept that.
yet, after asking me to propose solutions, you resist and call them ugly.
That was the only way I could get everything to compile on all platforms.
It seems to me from what you've been saying that your approach to solving the serialize( ... ) dispatching/customization problem here has been to try different configurations of the code until you could get it to pass select tests on certain platforms, without regard for standard conformance and theoretical portability.
That's only partly true. I start out with what I believe is standard conforming code. The I compile it on all my platforms and discover problems. Then try to make modifications so that it passes with all the compilers and still is standard conforming. BOOST macros play an important role here. Sometimes standard conforming code has to be suppresed and replaced with other standard conforming code - e.g ar.template register_type<my_class>() gets replaced with ar.register_type(static_cast<my_class *>(NULL)). (God I hope that's conforming.). In this case I had to confront the question of which namespace serializations of standard containers should be placed in and still have the code compile and function with all compilers. The first solution used either std or boost::serialization depending upon configuration macros. It seemed very arbitrary to me. By arranging things so that the serialize(..) template was allways called from within the boost::serialization namespace I thought I had fixed the problem by permiting the overloads to be found via ordinary lookup.
That's a well-known way to end up with code that doesn't work portably or in configurations you haven't tried (for example, hmm, let me think... when the order of headers changes).
I'm aware of this.
Then generated the requirement to address the issue in the documentation with a table on what the user should use. That's what I call ugly.
Huh? I didn't propose a table.
I was refering to my previous solution.
And, IMO there's nothing particularly inelegant about using a table in documentation; there's well-established precedent for it in the standard and Boost. Certainly documenting what the user should do is a must. So I don't see what you're unhappy about.
If you don't like having to tell users to do something special on nonconforming compilers, well, the answer is to either find a clean idiom that works everywhere (for this particular problem, many have tried -- I don't believe such an idiom exists)
The problem when one writes code which is to be portable accross compilers - say serialization of the std::set . Its not enough for it compile and run on my platform - it has to run on them all. So one ends up with #if ... all over the place to vary the destination namespace depending on whether or not the compiler supports ADL - that's ugly.
or stop supporting those broken compilers.
This the crux of the matter right here. From the prespective of two-phase lookup - they're all "broken" except CW which can't use the most interesting parts of the serilization library because its broken in other ways. I made one choice - you would make another.
Read the passage of the standard I quoted to you, and look carefully at the example above. Do your homework.
I'm trying.
Lots of generic libraries have a similar dispatching issue to address, e.g. Boost.Range. There's a nice, free online compiler againist which you can test your 2-phase problems.
I downloaded and installed comeau 4.3 sometime ago specifically in order to be able to test this. I still use it to compile all the library modules and tests as a double check. They all pass. Alas, they don't link due to some collision with the Boost Test library that cropped up after 1.32. Now I'm informed that we have the test compile time switches set so supress two-phase lookup (or parts of it) so I have no "conforming" compiler available. This is a hinderence to addressing problems such as this.
I've quoted the standard chapter and verse. I've given you simple example programs that demonstrate the problem. I don't know what more I can do... do I need to build a program that actually uses the serialization library before you'll believe me?!
That's what I'll have to do. FWIW its not that don't believe you're correct about the way two-phase lookup works. But I"m curious to know why things have worked so well so far. Is it because no one is using conforming compilers? Is it because common use cases don't trip on this? This is so far unexplained. The only way I'll discover this is by "doing my homework" which I haven't been able to get to. Maybe there is a real simple solution here. The relevent passage in the documentation currently states: Namespaces for Free Function Overrides For maximum portability, include any free functions templates and definitions in the namespace boost::serialization. If portability is not a concern and the compiler being used supports ADL (Argument Dependent Lookup) the free functions and templates can be in any of the following namespaces: a.. boost::serialization b.. namespace of the archive class c.. namespace of the type being serialized So if I were to change it to the following would that be satisfactory? Namespaces for Free Function Overrides If your compiler supports two-phase lookup and ADL (Argument Dependent Lookup) the free functions and templates can be in any of the following namespaces: namespace of the archive class namespace of the type being serialized If your compiler doesn't support two-phase lookup but it does support ADL free functions and templates can be in any of the following namespaces a.. boost::serialization b.. namespace of the archive class c.. namespace of the type being serialized If your compiler doesn't support ADL free functions and templates must be in the boost::serialization namespace. Of course that begs the main question I set out to answer. How to make ones code work on all boost platforms - but we can just leave that to the judgement of the library user. Robert Ramey