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.