1

GCC can compile the code below but VS2010 express couldn't:

#include <iostream>
#include <queue>
using namespace std;

struct A
{
  deque<A>::iterator next;
};
int main()
{
  A a;
}

Error message:

error C2027: use of undefined type 'A' main.cpp(6) : see declaration of 'A' main.cpp(7) : see reference to class template instantiation 'std::deque<_Ty>' being compiled 1> with 1> [ 1> _Ty=A 1> ]

Is there any way to solve this problem except using pointers?

Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65
Anton Agapov
  • 143
  • 1
  • 9

1 Answers1

1

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.

Community
  • 1
  • 1
Michael Karcher
  • 3,803
  • 1
  • 14
  • 25
  • Thank you for your answer! The task was to design a class which can contain a reference to it's matching (by some rule) pair. There are two deques that contain objects which we compare to each other and build pairs. So I know that we can complete these task by using pointers, but it seems to me that expression like this `next = &(*(itertor_to_object));` is not very beutiful solution :-). – Anton Agapov Jul 15 '15 at 10:33