On Wed, Aug 31, 2022 at 6:00 PM Marcin Jaczewski via Std-Proposals <std-proposals@lists.isocpp.org> wrote:

More a new version/flavor of C++, it could be in some way compared to the "epoch" proposal
but is more fine grained as you can specify each class for what version it belongs to.

> > extern "C++20" struct A
> > {
> >     std::_30::string x; //newer version of string for some improvements
> >     std::_20::vector<bool> y; //our favorite version of current vector :>
> > };
> >
> > inline A Create(const std::string& x) //current `string` based on compiler option

It seems like you're just reinventing "inline namespaces" — a feature which is already present in C++, and was added basically because people thought it might help with this kind of issue, but in fact it does not.

namespace std {
#ifdef OLD_ABI
    inline namespace older {
        struct string { int x, y; };
    }
#else
    inline namespace newer {
        struct string { int y, x; };
    }
#endif
} // namespace std

void myFunction(std::string x);
  // mangles as _Z10myFunctionNSt5older6stringE when defined(OLD_ABI)
  // mangles as _Z10myFunctionNSt5newer6stringE when !defined(OLD_ABI)

One problem this doesn't solve is user-defined types.

struct Name { std::string n; };
void myFunction(Name x);
  // mangles as _Z10myFunction4Name no matter what ABI we're using

You go on to talk about programs that use both ABIs for std::string simultaneously — i.e., std::older::string and std::newer::string coexisting in the same program. That's generally not possible, or at least will cause problems.  Recommended search terms: "semver", "diamond dependency".
https://abseil.io/resources/swe-book/html/ch21.html
Even if it were physically possible for two versions of std::string to coexist in your program, you wouldn't want that, because it would mean your program was twice as big as it ought to be.

HTH,
Arthur