tags:

views:

224

answers:

3

So I'm trying to get some code that is written for gcc to compile on Visual Studio 2008. I have a problem that I have narrowed down to this:

class value_t
{
public:
  typedef std::deque<value_t>         sequence_t;
  typedef sequence_t::iterator        iterator;
};

This code fails:

1>cpptest.cpp
1>c:\program files\microsoft visual studio 9.0\vc\include\deque(518) : error C2027: use of undefined type 'value_t'
1>        c:\temp\cpptest\cpptest.cpp(10) : see declaration of 'value_t'
1>        c:\temp\cpptest\cpptest.cpp(13) : see reference to class template instantiation 'std::deque<_Ty>' being compiled
1>        with
1>        [
1>            _Ty=value_t
1>        ]
1>c:\program files\microsoft visual studio 9.0\vc\include\deque(518) : error C2027: use of undefined type 'value_t'
1>        c:\temp\cpptest\cpptest.cpp(10) : see declaration of 'value_t'

However when I try this with std::vector, it compiles fine:

class value_t
{
public:
  typedef std::vector<value_t>        sequence_t;
  typedef sequence_t::iterator        iterator;
};

What's wrong? I have tried adding 'typename' everywhere I can think of, but at this point in time I'm thinking it's just a bug in the Dinkumware STL. Can anyone explain what's happening, and/or offer a solution? Thanks.

+1  A: 

You are trying to use a class within itself in a template. How does it resolve this? I don't know that I have ever tried to do this, but is this even possible? I don't know why it works for std::vector, but my assumption is that it is wrong. You are defining a class, and using that definition in the definition. Seems wrong to me. Good luck on this one, I'll be interested to see some deeper answers myself...

Jay Kramer
It works for std::vector, and on gcc this code compiles fine too. I guess as long as sizeof(class) is known that's enough. It tripped up the people in the link I posted in the comment too, apparently. I've been doing this with vector for years - just a coincidence that it worked then, I guess.
Roel
+5  A: 

I think the problem is that value_t is an incomplete type until you reach the end of the definition. Trying to use an incomplete type as the template parameter for a standard container isn't really supposed to work. It can/will happen to work under some circumstances, but if it failed with all standard container types, that still wouldn't signal any kind of bug. The standard requires it to be a complete type, so if it's not, you get what you get -- it probably should fail consistently, but if it happens to work, there's nothing wrong with that.

Jerry Coffin
+7  A: 

Its undefined behavior. See this link on c.l.c++.moderated

Snip from Daniel K's answer :-

the C++ standard (both C++03 and C++0x) says that what you are trying causes undefined behaviour, see [lib.res.on.functions]/2:

"In particular, the effects are undefined in the following cases: [..] — if an incomplete type (3.9) is used as a template argument when instantiating a template component."

Abhay
Thank you, that thread explains it in the most detail I could ever want. Guess I'll have to change the code.
Roel