Boost logo

Boost :

From: Gavin Lambert (boost_at_[hidden])
Date: 2019-06-26 08:01:01


On 26/06/2019 19:18, Dominique Devienne wrote:
> On Wed, Jun 26, 2019 at 2:25 AM Gavin Lambert wrote:
>> The specialisation syntax in C++ is fundamentally flawed, and in my
>> view, should absolutely never be used by anybody.
>>
>> One such example of this is that (especially for header-only libraries,
>> although with care this can also be used for compiled libraries) it is
>> very useful to be able to allow multiple versions of a library to
>> co-exist through external namespacing:
>>
>> namespace v1
>> {
>> #include <library_v1/lib.hpp>
>> }
>> namespace v2
>> {
>> #include <library_v2/lib.hpp>
>> }
>>
>> Most of the time this Just Worksâ„¢; one of the cases where this
>> completely falls over is that in this scenario it is impossible for the
>> library to define any specialisations in the std namespace (or indeed
>> any other namespace outside of its internal bubble, including the global
>> namespace).
>>
>> Using ADL is much more convenient; explicit policy arguments can be used
>> as a fallback when ADL is not possible.
>
> This subject is one I've struggled with, going back and forth in my
> own closed-source libraries between traits, functions, combination,
> what not; and that I never felt happy about. Do you know of any good
> treatment on the subject that details the pros and cons of the
> various approaches? I've seen it mentioned in Boost reviews as well,
> notably the Boost.Convert one, with Steven especially, but I clearly
> lack the depth to fully grasp it.
> Any good sources on that subject?

Not that I'm aware of, but I'm not really an expert on the subject
either; it's just an occasional pet peeve of mine.

It's something that would easily be solvable if the language allowed
scoped declarations; for example, instead of declaring:

     } // whoops, we have to close our namespace
     namespace std { // and hope that this is ::std, but it might not be
         template<>
         struct hash<my_ns::Type>
         { ... };
     }
     namespace my_ns { // and back we go again

If you could instead just declare:

     template<>
     struct ::std::hash<Type> // my_ns::Type, since still inside my_ns
     { ... };

This would be immune from the above problem, and much much more
convenient to use.

But sadly we apparently don't live in a sane world.

(It's more debatable whether my_ns should still be in scope inside the
body of the specialization. Convenience says yes; consistency says no.
  Compromise suggests perhaps only my_ns::Type is visible, due to being
a template argument.)

There have been a few standards proposals to fix this for std::hash in
particular by doing something different. But currently it looks like
the standard in general is heading down the track of defining even more
things that need to be specialised, rather than the reverse.

I'm not aware of any general fix being proposed, but I also don't really
follow these things.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk