c++iteratorlanguage-lawyerstdmapreverse-iterator

std::map::reverse_iterator doesn't work with C++20 when used with incomplete type


I noticed that the use of std::map::reverse_iterator in the below example doesn't work with C++20 but works with C++17 in all compilers.

Demo

Demo MSVC

#include <map>
class C; //incomplete type 

class Something
{
    
    //THIS WORKS IN C++17 as well as C++20 in all compilers
    std::map<int, C>::iterator obj1;
    
    //THIS DOESN'T WORK in C++20 in all compilers but works in C++17 in all compilers
    std::map<int, C>::reverse_iterator  obj2;
};

int main()
{
    Something s;
    return 0;
}

My question is what changed in C++20 so(such) that the use of std::map::reverse_iterator stopped working in all C++20 compilers.


Solution

  • It works by chance pre-C++20, by standard it's UB to use incomplete types in std containers (with the exception of vector, list and forward_list since C++17). See here. Thus, it may work and may stop working at any time, but basically anything can happen and it should not be relied on.

    If being able to store an incomplete type is a hard requirement for your use case, you may want to check boost::container.