Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are only these C++ standard library containers guaranteed to allow incomplete types?

Tags:

c++

c++17

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?

like image 907
Brian Bi Avatar asked Sep 12 '19 16:09

Brian Bi


2 Answers

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).

like image 172
Marshall Clow Avatar answered Sep 19 '22 03:09

Marshall Clow


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.

like image 27
Maxim Egorushkin Avatar answered Sep 19 '22 03:09

Maxim Egorushkin