First, some context: I'm trying to use the Pimpl idiom in the way Herb Sutter presented it in the solution to his GotW #101. This would look like this in the header file:
#include "pimpl_h.h"
class widget {
class impl;
pimpl<impl> m;
// ...
};
The implementation would look like this:
#include "pimpl_impl.h"
class widget::impl {
// ...
};
The problem I am trying to solve appears when a class using this technique uses another Pimpl class for their own implementation. It includes the "pimpl_impl.h", so the compiler (in my case VC++ 2013) gains knowledge of the concrete template for pimpl <impl>
of the other class and tries to implicitly instantiate it, which of course results in compilation errors as it does not know about the implementation of that class.
To solve this, I have used the new "extern template" feature of C++ 11 in the header:
#include "pimpl_h.h"
class widget {
class impl;
pimpl<impl> m;
// ...
};
extern template pimpl<widget::impl>;
This should guarantee that only the explicit instantiation I have in the compilation unit providing the implementation of widget::impl
leads to an actual instantiation. This compiles without a problem, but IntelliSense shows me an error:
Error: 'extern template' cannot follow explicit instantiation of class "pimpl<widget::impl>"
As "extern template" cannot be used inside of a class declaration, I cannot write
#include "pimpl_h.h"
class widget {
class impl;
extern template pimpl<impl>;
pimpl<impl> m;
// ...
};
and I can't think of any other way. My question is:
Is IntelliSense wrong and the compiler right in accepting my code? Or is it just coincidence that VC++ compiles this and it isn't valid C++?
If my solution is not valid C++, what alternatives do I have?