That doesn't fully describe the picture. Beyond declaration and implementation there is also usage. You also can not use any interface utilizing an incomplete type even when you do not directly manipulate the type and the type is complete for implementation of that interface. (Granted, you'd probably only run into this problem with inline forwarding functions.)
May-be you are right and there are some hidden traps, but I'm talking about declaring a function that passes and returns incomplete types by value (which compilers accept quite happily), and you are saying that at the point of implementation/definition the type must be complete (which I agree with, of course).