C++ interface/API versioning using typedef and namespace aliases

Have you ever had to support applications compiled on an old version of your C++ library? And had to sacrifice sensible naming and reuse due to binary compatibility? And the "bridge pattern" (hiding implementation behind a pointer) won't work due to performance or inheritance?

You can on most OSes use shared library versioning but it requires use of linker scripts and/or compiler-specific #pragmas. Instead of relying on OS support for versioning of shared libraries you can do something simpler.

Versioning using typedef

typedef does not create a new type name - it only creates an alias during compilation. The generated code refers to the underlying type name. This can be used for making versionable classes.

First version of headerfile

class X__v1 {
	...
};

typedef X__v1 X;

second version of headerfile

class X__v1 {
	...
};
class X__v2 {
	...
};

typedef X__v2 X;

And the source using the API remains the same:

X x;

When programs are compiled against the first version of the headerfile they will bind to the X__v1 name. If you recompile the program against the second version of the headerfile they will instead bind to X__v2 automatically. Also quite important is that the library implementation is much easier than with OS versioning (eg. your can have both X__v1 and X__v2 in the same source file).

Versioning using namespace aliases

If you use namespaces you can use aliases:

First version:

namespace A__v1 {
  class X ...
  class Y ...
  class Z ...
}
namespace A = A__v1

Second version (where the X class is changed):

namespace A__v1 {
  class X ...
  class Y ...
  class Z ...
}
namespace A__v2 {
  class X ...
  using A__v1::Y;
  using A__v1::Z;
}
namespace A = A__v2