
On Wed, Nov 4, 2009 at 6:52 PM, Nigel Rantor
Geoff Hilton wrote:
I'm writing a public api for a product which will be bundled as a precompiled dll or binary and one of my goals is binary compatibility (if not across major versions, at least across minor). I'd like to implement the pimpl idiom and reference counting for the handle classes as appropriate, but I'm worried about all the typical stuff (exception safety, memory leaks, etc) and I'd rather not reinvent the wheel.
eg. template<typename T> class MyClass { public: T foo(); private: boost::shared_ptr
impl; }; Using boost::shared_ptr would be great, but this means clients of my code would have to have the same version of boost installed that we use, and I imagine this could cause conflicts in the event that they happen to use boost (and a different version of it). I'd rather not include more code dependencies than I absolutely have to, especially if they may prove problematic in the future. What do I do? I know I'm not the first in this situation. How often have others opted for this dependency as opposed to furnishing their own alternative that would avoid additional dependencies (at the expense of the benefit of time-tested code)?
One way around this is to include the boost libraries you require in your own distribution with the top-level namespace appropriately renamed. Yes, this is ugly, it means distributing the code and modifying it so that all the namespaces are different.
e.g. boost::shared_ptr -> boost_1_38::shared_ptr
Within your own code you can use a namespace alias to make it easier to move to new versions of boost as and when required.
e.g. namespace geoff_boost = boost_1_38;
Then use geoff_boost::* within your own code. You can then move your own code to new versions of boost by changing that single alias.
Externally you can provide typedefs to smart_ptr classes.
e.g. namespace package { class foo; typedef geoff_boost::smart_ptr<foo> foo_ptr }
So clients of the library deal with names like package::foo_ptr and have no idea that behind the scenes you're using a specific version of boost hidden behind a couple of namepsaces...
It's a trade-off - you have to do something nasty, but the client gets to see nice names, you get to re-use solid code but you'll have to live with the dirty feeling of modifying the boost headers (a perl script or two, so you can do it automatically for a new version) and re-distributing them.
The tool "bcp" that comes with boost can take out parts of Boost that you want to include in your projects, and as I recall it can also rename namespaces automatically (either that or it is a feature being worked on).