This is the old trope of asking for proof from one side in a forum where things are discussed freely. I could turn it around and ask you to justify all the new "features" added to say C++11..20. I am here for the rest of time.
But to give a few concrete examples;
>Which “so called problems”?
Apparently "variants" were introduced to solve problems with POD "unions". Mere complexity for not much benefit. Nobody i have worked with ever said "unions" were difficult to use.
>Which “established code patterns?”
RAII as a solution to People harping about memory problems. I have written entire protocol message libraries just using RAII to avoid memory leaks.
>Why “it means nothing” and to whom?
When "Modern C++" proponents say everything should be written with the new features using hand-wavy phrases, "it means nothing" to experienced programmers. If we find a feature useful to model a concept and/or express something we will use it; but always weighed against how complex it is to read and maintain. A good example is template meta-programming taken too far.
The key reason C++ took off was because it added minimal "Zero-Overhead abstraction" constructs over the baseline "low-level and simple" C core. Suddenly programmers could have their cake and eat it too. The evolution of C++ should have continued in the same spirit but instead in a misguided effort to compete with later and differently designed languages a lot of complexity has been added for not much apparent benefit.
Variants are meant to introduce a tagged union like data structure into C++.
You can do this without variants by manually defining your own unions and managing the tag yourself, but this is very not type safe and requires extra boilerplate code to manage!
Maybe you have never used and don't care about this feature but it's actually pretty useful! Tagged unions make representing certain types of data very elegant, for example nodes of an AST or objects in a dynamic programming language. You can use OOP patterns and dynamic dispatch to represent these things as well, but I think tagged unions are a better fit, and you get to eliminate a virtual method call by using std::visit or switching on the tag.
I suspect that maybe you have never been introduced to sum types in general which is not uncommon! I am curious if you have experience with using them or not?
variants/sum types is not some earth-shattering concept but has been implemented using tagged unions in C from the beginning of time. At one point in my career i had an occasion to write a "spreadsheet-like data structure" (basically a linked list of linked lists) in three different ways one of which was using a tagged union for the data nodes. The point is that people trivially rolled their own when needed and did not clamour for language/library additions.
I have already pointed out in some of my other replies why it is wrong to consider a variant as a replacement for POD union.
I do realize people have been using tagged unions for a long time. Having some library helpers goes a long way in making them more usable and more expressive. Having them built into the language as a first class feature is even better yet, but std::variant is a nice middle ground.
Technically you can implement it manually, but the same thing could be said about all language features, even in C. We don't need actually need structs built into the language, we can just allocate blocks of data and handle the offsets by hand. We don't need functions, we can just push stuff to the stack and use the call opcode. The same goes for various loop constructs, goto can do everything "for" and "while" can do!
I don't think "we used to roll our own X back then" is a strong argument for something being bad or unneeded. Abstractions are all about allowing the computer to do work for us, and making things less error prone and more expressive. This is why we have programming languages to begin with and don't write everything in assembly!
Language design is a fine balance; the addition of Abstraction Features has to be balanced against the cognitive load it imposes on the Programmer. These abstractions also need to be tailored to a computation model supported by the language. For example, the Niklaus Wirth school of language design was famous for insisting on minimalist languages; You only added features if they were "needed" to support the model of computation and all extraneous/trivial features were omitted. C++ took the opposite route from the beginning which was ok to a certain extent since it increased the expressive power of the language (eg. multi-paradigm). But over time the balance is being lost and the cost of cognitive load is outstripping the benefit of an added abstraction. This is bad and not welcome. So looked at in this light how many of the features in Modern C++ are essential and how many are extraneous (eg. Concurrency features = Essential, variants/syntactic annotations/etc. = Extraneous)? That is the fundamental issue.
> But that is the point; "union" is supposed to be a POD
no it's not. it's fine to have non-POD unions - but you have to be careful to call constructors and destructs of non-POD's explicitly. thus, variant which automates that.
Also, I didn't talk specifically about unions, but about sum types. There is a need for saying that an object X can be of type A OR type B, no matter the properties of these types.
Only from C++11 (or is it later?). So a problem was created by relaxing the existing requirements for a "union" to which a solution was proposed by adding a "variant"? Something which had no runtime overhead (but UB) now has runtime overheads.
I'm just pointing out that you didn't have anything concrete in your messages.
> Apparently "variants" were introduced to solve problems with POD "unions". Mere complexity for not much benefit. Nobody i have worked with ever said "unions" were difficult to use.
First link in Google, how is moving from undefined behavior and not needing manually declare type of union (sic!) is a "mere complexity for not much benefit"?
> Nobody i have worked with ever said "unions" were difficult to use.
Sure, enough people say that about for and while loops while avoiding functional patterns like a plague.
> RAII as a solution to People harping about memory problems. I have written entire protocol message libraries just using RAII to avoid memory leaks.
Which "modern, overhead features" are solved by RAII?
> When "Modern C++" proponents say everything should be written with the new features using hand-wavy phrases, "it means nothing" to experienced programmers. If we find a feature useful to model a concept and/or express something we will use it; but always weighed against how complex it is to read and maintain. A good example is template meta-programming taken too far.
Who are these experienced programmers and how do you define those? Your circle of people?
> If we find a feature useful to model a concept and/or express something we will use it; but always weighed against how complex it is to read and maintain.
Modern features are literally easier and less complex than old way. Like in the variant example.
> A good example is template meta-programming taken too far.
And how often "modern c++ proponents" suggest meta-programming to solve ordinary problems? Because everywhere I've encountered C++ discussions, those were resorted either for internal usage or suggested to avoid at all.
> The key reason C++ took off was because it added minimal "Zero-Overhead abstraction" constructs over the baseline "low-level and simple" C core.
There's no key reason C++ took off. It took off, because it took off.
> The evolution of C++ should have continued in the same spirit but instead in a misguided effort to compete with later and differently designed languages a lot of complexity has been added for not much apparent benefit.
There's a reason why those differently designed languages were defined differently. Maybe instead of blindly hating evolution, try understanding the reasons behind it.
And you have mistakenly assumed that i am "blindly hating evolution". The distinction i make is between "needs" and "wants"; much of what has been added in Modern C++ is "wants".
>First link in Google, how is moving from undefined behavior and not needing manually declare type of union (sic!) is a "mere complexity for not much benefit"?
Because you have not understood the definition and guarantees of a "union"; and UB is not always a bad thing. "union" is explicitly defined to be a POD with all it entails. The stackoverflow answer does not provide anything new. If you want something more, you code it explicitly when needed. No need to burden the language; in fact it creates more problems because "variant" does not guarantee layout compatibility.
>Sure, enough people say that about for and while loops while avoiding functional patterns like a plague.
Of course familiarity and clarity always trumps "new patterns".
>Which "modern, overhead features" are solved by RAII?
The harping on "never use naked pointers" in your code.
>Who are these experienced programmers and how do you define those? Your circle of people?
Of course; It should be the same for you and everybody else too!
>Modern features are literally easier and less complex than old way. Like in the variant example.
This is what we are debating; it is not a fact that you seem to assume.
>There's no key reason C++ took off. It took off, because it took off.
There is always a tipping point. In C++'s case it was compatibility with C and new language constructs for higher level abstractions.
>There's a reason why those differently designed languages were defined differently.
Exactly; Each starts with a Computation Model and evolves a syntax to that model. The evolution should not be willy-nilly dumping everything and the kitchen sink into a language. C++98 was complicated enough but still manageable but what has happened from C++11 onwards is just too much complexity requiring even more effort from experienced programmers. You cannot hand-wave it away by saying "Modern C++ is a whole new language so forget baseline C/C++ cores" which is quite silly.
I can continue.