It's explicitly legal. The rule is that the types used to instantiate
a template in the standard library must be complete, unless otherwise
specified. In the case of unique_ptr
, §20.7.1/5 says “[...] The
template parameter T of unique_ptr may be an incomplete type.”
There are certain operations on the pointer which require a complete
type; in particular, when the object will actually be destructed (at
least with the default deleter). In your example, for example, if
A::~A()
were inline, this might cause problems. (Note that if you
don't declare the destructor yourself, it will be inline. Which
partially defeats the purpose of using std::unique_ptr
.)