std::string is in the STL. So is std::string_view. There are language changes as well that enable some of the new STL additions but some are just STL updates and you could "backport" them so to speak. Or do the same thing but yourself.
Making std:: verboten these days would likely be a mistake, though. There's so many things that are just not controversial and not worth re-implementing. Like std::unique_ptr. Or std::array.
Most of the containers are still better off ignored, though, many of them unfixable. The least worst of them is std::vector and it's still _ok_ but even there things like absl::InlinedVector are worth a strong consideration instead ( https://github.com/abseil/abseil-cpp/blob/master/absl/contai... ). Or boost's small_vector ( https://www.boost.org/doc/libs/1_60_0/doc/html/boost/contain... )
std::map, for example, is only appropriate if you need a red-black tree specifically. Which almost nobody does. std::unordered_map is less awful, but abseil has a literal straight upgrade. With the same API. So... why would you pick the slower thing when you're using C++? std::vector is only really appropriate if you know you never have small vectors, which is again a more obscure situation.
That assertion makes no sense at all. The stl contrainers work very well as basic generic containers that can safely be used for pretty much any conceivable use where performance isn't super critical. I'm talking about cases like, say, you need to map keys to values but you don't really care about performance or which specific data structure you're using. That's stl's domain: robust, bullet-proof implementations of basic data structures that are good enough for most (or practically all) cases with the exception of a few very niche applications.
If you happen to be one of the rare cases where you feel you need to know if a container is built around a red-black tree or any other fancy arcane data structure, and if this so critical to you that you feel the need to benchmark the performance to assess whether you either need to use non-defaults or completely replace parts or the whole container with a third-party alternative... Then and only then the stl is not for you.
You're arguing it's better to use something that's across the board worse for nearly every user, and by a lot, just because... why? It's slightly more convenient?
It really isn't. The whole STL is, by design, a template library packed with generic data structures that are designed to have very robust defaults and still be customizable and extensible.
When the defaults are good enough, which is the case in general, the STL will do. If you have a niche requirement (say, games) or feel adventurous, you adopt custom and/or specialized solutions.
This has been the case since the STL's inception. They are the standard, default library. I can't understand how someone is able to miss this fact.
No it isn't and no it's not. There are even platforms where an STL isn't even provided out of the box, you have to pick one. And there's quite a few at that - libc++, libstdc++, stlport, etc...
But clang, g++, etc... they don't care. To them it's just another library you're linking against, no different from any other dependency. They don't provide it, they don't care. It can even be quite a pain in the ass to use the "native" STL of a given compiler, like trying to use libc++ with Clang on most Linux distros.
As having multiple implementations to choose from, that is the beauty of language standards.
Abseil and boost do not fall under that umbrella, and I belong to the C++ subculture that never ever touched them, or plans to.
eg. to use an 'int' you just declare one and use it. To use strings, you need to include <string.h>.
java.util.Vector is standard as well but you'd be laughed out of a code review if you tried to use it anywhere. Similarly std::auto_ptr is in the standard, and is universally agreed to be trash to avoid like the plague. So much so it was (eventually) removed. The container section of the library has just sadly not had the same deprecation & removal of bad code put into it.
The claim was "STL containers are the sane default" not that "STL containers are more available". I stand by that claim being wrong. You have so far not actually attempted to counter it on any technical grounds, just bad appeal to authority fallacies.
Likewise std::auto_ptr got replaced by std::unique_ptr.
As you see the standard library keeps the knowledgable developers covered, no need to look elsewhere.
You are indeed wrong.
Now it's the Standard Library like in any other language.
Mixing and matching compilers and standard libraries is not only possible it's common. Especially when cross-compiling enters the picture.
There is no bundling of any kind in any concept of that word, practically or technically, between C++ compilers and standard libraries. This is also a good thing, it makes porting C++ to new platforms far more easier than it otherwise would be.
They even have independent feature compliance sections. Clang & G++ both support new C++ features independently of whether or not their "bundled" standard library does yet.
Chill on the name calling.
> Clang on Windows is distributed to use the system installation of libstdc++
Windows doesn't have a default system installation of C++ at all nor is it libstdc++. You can use clang on windows with libstdc++, but that's a MingW port and not at all "native" to the platform.
Windows' standard C++ runtime is the Visual C++ Redistributable and there are many versions of it that all coexist simultaneously. Which one is used depends on what the application was compiled against, there is no "system version" of it. Runtimes that Clang can also use.
> That's because libc++ is clang's experimental implementation of the C++ standard library
There is nothing experimental about libc++ at all. It is the standard for some platforms, like Android and MacOS/iOS. In fact Apple removed support for using libstdc++ entirely with Xcode 10. And before Xcode 10 you got a choice between libstdc++ & libc++, because again the C++ standard library is not bundled. Similarly on Android there used to be a choice between not just libstdc++ and libc++ but also stlport was an option. Now only libc++ is supported, and it's not provided by the system at all.
There are lots of subtleties STL containers have to worry about in designing containers, regarding everything from iterator & pointer invalidation to allocation and allocator propagation. All this is because they're designed to be general-purpose and support most conceivable use cases. Their replacements have to trade off requirements in order to get better performance or otherwise improve on some axes.
It only breaks swap of the container itself during iteration. Which is a super niche condition.
And that swap also invalidates some of std::vector's iterators as well - specifically the end() iterator.
> They also really only make sense for tiny objects (ints, etc.) given you don't want a pickup truck's worth of data on your stack. They're most definitely not general-purpose.
Of course they are still general-purpose. They can (and do) specialize on the size of the object being contained. The only reason std::vector doesn't also have SSO is because it's an ABI break. Not because it's better in some way or less fragile. Legacy is the only reason.
And they don't invalidate the iterators that point to actual elements, which was kind of the entire point I was making. Don't let that stop you from trying to make it look like I'm just blurting out nonsense, though.
std::function is fine for prototyping, but its size hit is extreme, so in embedded code we use other implementations. But where size and speed doesn't matter? Why bother?
These are all largely header libraries. You're already hauling in a dependency, and in every c++ file that uses it at that.
> std::function is fine for prototyping
std::function isn't part of the containers library of the STL (containers being all the stuff here: https://en.cppreference.com/w/cpp/container ). I agree std::function is fine, it even has a pretty reasonable small-size optimization.
That's not even true for boost, no matter if they always advertise that. The lib is also notorious for bad decomposability (using only a subset without installing the whole monster). Not to speak about idiosyncratic naming and build system, making it sometimes hard to include it in meta builds of other libraries and frameworks.
In sum: Anyone sensible, regarding different kinds of footprint and dependencies will think twice, before pulling in these kind of libraries.
Boost is better thought as a loose collection of libraries that try to follow some common design principles instead of a single monolithic library.
I can't defend the build system though.
App installation is a one time cost anyways. Did you mean s/download/startup/?
Being a polyglot developer, with Java, .NET and C++ as my favourite stacks, means I don't suffer from Java hate from C++ point of view, rather enjoy how one can combine their strengths to achieve a good outcome.
Having said that I think using abseil's containers is reasonable, even as a default, if you can afford the dependency.
> std::unordered_map
AFAIK unordered_map is the most awful of all standard containers.
I want my OWL, VCL back, not an hash table able to do lookups in micro-seconds
The point I was trying to make, was that from productivity point of view, there are more relevant stuff to fix in C++ than algorithm complexity of STL implementations.
Like catching up with what Java 5 standard library offers for networking and parallel/concurrent programming.
If you care about performance then it's not. (And if you don't care about performance then why are you using C++?) The standard requires that `insert` will not invalidate iterators, which basically forces everyone to implement `std::map` as a red-black tree, and those are pretty bad performance-wise on modern hardware mostly due to cache misses.
> If you need fast O(1) look up std::unordered_map is really not fit for purpose and requires you to come up with an hash function.
Modern hash table implementations (along with a modern hash function) are exactly what you should use if you need fast average-case O(1) lookup, so I'm confused why would you say that it's not fit for purpose? Unless you specifically meant only `std::unordered_map` which, yes, is pretty atrocious performance-wise (again, due to the iterator invalidation requirements).
Not sure which part of std::string you're referring to but the compiler generally doesn't contain any knowledge of the library itself. It does goes the other way though where the standard library has to know how to implement certain functionality on a given compiler (some type traits functionality IIRC isn't possible to implement without compiler builtins that expose the AST to you). I think Rust has taken a more sustainable approach with their macro system which can modify the AST instead of relying on builtins but even in Rust I suspect they use builtins in certain places of their standard library.
Today's STL implementations are going to be better performing and more robust than anything you'd write yourself so generally a good idea to stick to it as a rule of thumb for the majority of code.
There are places in the rust standard library which just omit the implementation because it's magically filled in by the compiler based on the type and function names. Which, for really low-level and fundamental functionality, seems fair game to me.
* various operator new * all the type traits * a lot of the names inherited from the C library
compilers could do much more, but in general they prefer to implement generic optimizations instead of targeting a specific library name (for example removing allocation for stack allocated std::strings was not done until the generic removal of alloc/free was implemented).
I believe some standard-library type-traits cannot be implemented without specific compiler support.
[0] https://github.com/boostorg/type_traits/blob/059ed883/includ...
I think that’s still pretty common, especially in game development and/or when compiling with exceptions disabled. AFAIK std::vector is fine, and probably std::string, but for things like std::[unordered_]map, Abseil and Folly have equivalents that are slightly non-standard and much faster.
(In old man voice) We ended up rolling out own stuff and marking std:: verboten. Why? Stl was too slow, too verbose, and too hard to grok the stack when debugging. We ended up with less memory fragmentation, less dangling ptrs, etc etc. In the rare case there was something in STL that was actually cool (or faster, which was very rare), we'd gut it and reef out the part that was cool to use in our implementation.
I presume these comments aren't popular (sorry about that, but this is during 90s and early 00s when dev cycles were clearly different). Eg. We had string classes in all different flavours, some would interop, some wouldn't. Eg. We had tree and hash classes that, while templateable, had a few core implementations that made compilation fast. We had various ptr management systems (ref counted, stack based, etc).
We made STL between verboten in all APIs because we been burnt so many times using (/trying to use) other ppls APIs that exposed STL in its library. (We were exclusively a windows shop, if that helps understand my confusion... PS. I'm retired these days and have been out of the c++ game >10yrs)