A teammate of mine regularly uses a variation on pimpl, which he does like this:
Foo.h:
namespace { struct Impl; }
class Foo
{
public:
Foo();
~Foo();
void Bar(int n);
/* ... */
private:
std::unique_ptr<Impl> _impl;
};
What's happening here is that he's forward-declaring the implementation class to be in the anonymous namespace. Then he'll define the Impl
class within Foo.cpp .
So the definition of the structure ::Impl
will be available to Foo.cpp
's translation unit. Other code include Foo.h
will raise a warning, because they obviously can't access ::Impl
defined in Foo.cpp
. But then, we don't need them to - it's a class meant to be used in Foo.cpp
only; we don't want it visible or known elsewhere.
And while we can certainly have a situation where on .cpp
file is including multiple headers, each declaring their own ::Impl
structures, these don't actually clash, because the structures are never used outside their respective translation units.
tl;dr: This looks weird, raises warnings, and looks as though it can cause clashes, but seems to actually work.
All that being said, I'm not comfortable with having something that raises warnings baked so deeply into our code (the more header files this is in, the harder it's going to be to take out.) It's also just a ton of warnings.
My teammate stands by this because it's simple, keeps the code definitions simple, and lets us use the short, consistent classname Impl
across all our code.
I'm not a stickler for coding conventions; if this is good practice for our use-case, I don't mind. But I would like to feel comfortable that this is safe and maintainable, and isn't going to blow up in our faces at some point.