It's a well-known fact that the C++ standard library containers, in general, cannot be instantiated with incomplete types. The result of doing so is UB, although in practice a given implementation will either accept the code without issues or issue a compilation error. Discussion about this restriction can be found here: Why C++ containers don't allow incomplete types?
However, in C++17, there are three containers that explicitly allow incomplete types: std::forward_list
(26.3.9.1/4), std::list
(26.3.10.1/4), and std::vector
(26.3.11.1/4).
This is the result of N4510. The paper notes that "based on the discussion on the Issaquah meeting" the decision was made to, at least at first, limit such support to those three containers. But why?
Because we know how to implement those containers to deal with incomplete types, without breaking the ABI.
std::array
, on the other hand, needs to know how big an element is (for example).
But why?
The reason incomplete types weren't allowed in the standard containers was that some containers can work with them, but some don't. They didn't want to think too much about this issue at the time and made a blanket prohibition of incomplete types in all standard containers.
Matt Austern documented that in his great article "The Standard Librarian: Containers of Incomplete Types", which is no longer available, but there are still quotes from it in Boost Containers of Incomplete Types.
This C++17 change does justice by undoing the harm inflicted by that blanket prohibition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With