Unless the standard explicitly states that incomplete types are legal, they are not legal. The specific section is 17.6.4.8 [res.on.functions], paragraph 2:
In particular, the effects are undefined in the following cases:
[...]
- if the incomplete type (3.9) is used as a template argument when creating an instance of the template component, unless this is specifically permitted for this component.
I do not think that any container is required to support incomplete types. Some of the smart pointers allow incomplete types. Out of my hands, I can't think of anything else that would allow incomplete types. A quick search for "incomplete" results in the following components that allow incomplete types as template arguments:
std::declval<T>()std::unique_ptr<T>std::default_delete<T>std::shared_ptr<T>std::weak_ptr<T>std::enable_shared_from_this<T>
In the sample code, std::map<int, A>::iterator creates an instance of the template with an incomplete type. As a result, the code leads to undefined behavior.
source share