As discussed for example in How come I can use a forward-declared class in a std::vector?, instantiating standard containers with incomplete types is undefined behaviour. To be able to access the iterator type of std::deque<A>
, it is required to instantiate this class, so the program you give has undefined behaviour. In this specific instance, in gcc undefined behaviour happens to be what you expect, while Visual Studio (with its Dinkumware Standard Library implementation) happens to fail to compile. It is likely that Visual Studio behaves different in Debug and Release mode, as in debug mode, the containers (and iterators) are much more complex to be able to check for many iterator abuses.
I was unable to quickly find a reference that declaring a pointer to an deque iterator where the element type is an incomplete type is allowed, and I am afraid that most likely replacing the iterator by an pointer to an iterator does not make this program defined (although it might make it work in more environments). If you were to replace the iterator by a pointer: This will surely work. I can't tell you whether it's the only solution, as you didn't clearly state what problem you try to solve. Possibly there is a different design approach to your problem that doesn't require this member variable.
std::unique_ptr<A> next;
works on MSVC2012 as the struct member. Perhaps something to do with how the standard library is implemented. I wonder if the standard insists that the construct is valid in this case, and perhaps not in your case. – Bathshebastd::deque<A>
inside the definition of A, even if you forward-declare it. As you can't name the iterator type ofstd::deque<A>
without instantiating it, I'm afraid this design will not work. – Michael Karcher