Andrey Semashev wrote:
The reality is that people end up using the boost equivalent components because they are forced to. Either because an upstream library requires it, such as Asio, or because it is already in the existing code base. Users have clearly indicated that they vastly prefer the std component over the Boost one regardless of whether the boost component offers additional value.
The only time the boost component is preferred, is when the additional functionality is so significant in the value that it brings, that it justifies the additional friction required to integrate the component. One example that comes to mind is Boost.Variant2.
New features added to std-flavored boost components become incredibly annoying years later when a project wants to switch back to the std equivalent, perhaps because they were finally able to upgrade to the latest C++. They discover they have to perform a non-trivial refactoring of the code base because over time these additional features that we added end up getting relied upon and cannot be extricated easily.
Sorry, I don't get this logic. You used a library for many years, with all its features. Now a standard component appears that lacks some of the features you use. Yet you still decide to switch to it despite the inconveniences and lacking functionality. And somehow the library that served you well is to blame for your trouble?
The way I see it, you (the one who decided to switch) is the one to blame in this situation. I don't mean this in an accusatory way, and there may be valid reasons to switch. But still it was your decision to switch despite the consequences, and thus you are the one responsible.
Both sides have a point here. Boost things that differ slightly from their standard counterparts do eventually become a problem when they become obsolete and undermaintained. (Things that fall into this category to some extent are Bind, Function, Ratio, Chrono, to a lesser extent Thread, etc.) I would like, for instance, to replace the entire implementation of boost::bind with `using std::bind;`, but I can't due to subtle and sometimes not so subtle differences. E.g. boost::mem_fn uses get_pointer(p) instead of *p, which allows useful things, and people did take advantage of it. There's no reliable way to know whether anyone in the real world still relies on these extensions or not, so it's hard to figure out whether breaking their code is worth it. Boost.Function is similar; there are subtle differences in behavior and not subtle extensions (allocator support) so it can't be replaced with a using declaration either. I did recently go ahead and make boost::ratio a using declaration. This potentially broke the code of anyone relying on the Ratio extensions. Fortunately, those were guarded behind a macro, so their use was probably limited. I would very much have liked to replace Chrono with using declarations as well, but that doesn't seem possible at the moment. All that said... If a library is not going to become undermaintained and obsolete due to the author abandoning it at some point, is going to be actively developed, and offers significant functionality over the standard counterpart that cannot easily be replicated by the user (e.g. local_shared_ptr, thread interruption), then said library won't ever be replaceable with a using declaration, and none of the above applies.