typedef and iterator 
Author Message
 typedef and iterator

Gurus,

I am facing a problem related to STL map. I have following code

///// MyClass.h //////////////////////////////////////////////////
#ifndef MY_CLASS_H
#define MY_CLASS_H

#include <map>
using namespace std;

class MyClass;

typedef map<MyClass, long> MyClassMap;
typedef MyClassMap::const_iterator MyClassMapIter;
// The program compiles successfully if the above line and all the
// references to MyClassMapIter are removed.

class MyClass
{
public:
 MyClassMapIter SomeFunc()
 {
  MyClassMapIter it = m_MyClassMap.begin();
  return it;
 }

protected:
 static MyClassMap m_MyClassMap;

Quote:
};

#endif //MY_CLASS_H
////////////////////////////////////////////////////////////////

////// EntryFile.cpp ///////////////////////////////////////////
#include "MyClass.h"

void main()
{
 MyClass mc;
 MyClassMapIter mci = mc.SomeFunc();

Quote:
}

///////////////////////////////////////////////////////////////

When I try to compile this code I get following error:

---------Configuration: MapIterator - Win32 Debug-------------
Compiling...
EntryFile.cpp
d:\program files\microsoft visual studio\vc98\include\utility(25) :
error C2079: 'first' uses undefined class 'MyClass'
        d:\program files\microsoft visual
studio\vc98\include\xtree(28) : see reference to class template
instantiation 'std::pair<class MyClass const ,long>' being compiled
        d:\program files\microsoft visual studio\vc98\include\map(46)
: see reference to class template instantiation 'std::_Tree<class
MyClass,struct std::pair<class MyClass const ,long>,struct
std::map<class MyClass,long,struct std::less<class MyC
lass>,class std::allocator<long> >::_Kfn,struct std::less<class
MyClass>,class std::allocator<long> >' being compiled
        i:\tntd\projects\scpiprojects\mapiterator\myclass.h(10) : see
reference to class template instantiation 'std::map<class
MyClass,long,struct std::less<class MyClass>,class
std::allocator<long> >' being compiled
Error executing cl.exe.

MapIterator.exe - 1 error(s), 0 warning(s)
-------------------------------------------------------------

Can anyone please explain me what is meant by this error and how to
remove it? I am using VC++ 6.0.

Thanks and regards,

~Ajit

"There are two ways of constructing a software design: One way is to
make it so simple that there are obviously no deficiencies, and the
other way is to make it so complicated that there are no obvious
deficiencies." - C.A.R. Hoare



Sat, 09 Apr 2005 01:50:52 GMT  
 typedef and iterator
According to C++ standard 17.4.3.6/2, using an incomplete type as a
template parameter for any STL template results in undefined behavior.

I don't see a quick workaround in your case. I'm afraid you are in for a
serious redesign.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


Quote:
> Gurus,

> I am facing a problem related to STL map. I have following code

> ///// MyClass.h //////////////////////////////////////////////////
> #ifndef MY_CLASS_H
> #define MY_CLASS_H

> #include <map>
> using namespace std;

> class MyClass;

> typedef map<MyClass, long> MyClassMap;
> typedef MyClassMap::const_iterator MyClassMapIter;
> // The program compiles successfully if the above line and all the
> // references to MyClassMapIter are removed.

> class MyClass
> {
> public:
>  MyClassMapIter SomeFunc()
>  {
>   MyClassMapIter it = m_MyClassMap.begin();
>   return it;
>  }

> protected:
>  static MyClassMap m_MyClassMap;
> };

> #endif //MY_CLASS_H
> ////////////////////////////////////////////////////////////////

> ////// EntryFile.cpp ///////////////////////////////////////////
> #include "MyClass.h"

> void main()
> {
>  MyClass mc;
>  MyClassMapIter mci = mc.SomeFunc();
> }
> ///////////////////////////////////////////////////////////////

> When I try to compile this code I get following error:

> ---------Configuration: MapIterator - Win32 Debug-------------
> Compiling...
> EntryFile.cpp
> d:\program files\microsoft visual studio\vc98\include\utility(25) :
> error C2079: 'first' uses undefined class 'MyClass'
>         d:\program files\microsoft visual
> studio\vc98\include\xtree(28) : see reference to class template
> instantiation 'std::pair<class MyClass const ,long>' being compiled
>         d:\program files\microsoft visual studio\vc98\include\map(46)
> : see reference to class template instantiation 'std::_Tree<class
> MyClass,struct std::pair<class MyClass const ,long>,struct
> std::map<class MyClass,long,struct std::less<class MyC
> lass>,class std::allocator<long> >::_Kfn,struct std::less<class
> MyClass>,class std::allocator<long> >' being compiled
>         i:\tntd\projects\scpiprojects\mapiterator\myclass.h(10) : see
> reference to class template instantiation 'std::map<class
> MyClass,long,struct std::less<class MyClass>,class
> std::allocator<long> >' being compiled
> Error executing cl.exe.

> MapIterator.exe - 1 error(s), 0 warning(s)
> -------------------------------------------------------------

> Can anyone please explain me what is meant by this error and how to
> remove it? I am using VC++ 6.0.

> Thanks and regards,

> ~Ajit

> "There are two ways of constructing a software design: One way is to
> make it so simple that there are obviously no deficiencies, and the
> other way is to make it so complicated that there are no obvious
> deficiencies." - C.A.R. Hoare



Sat, 09 Apr 2005 02:24:21 GMT  
 typedef and iterator

Quote:

> According to C++ standard 17.4.3.6/2, using an incomplete type as a
> template parameter for any STL template results in undefined behavior.

If this is the case then the statement

typedef map<MyClass, long> MyClassMap;

should also give error. But that does not happen. The error is given
only for the line with the iterator. Why does the typedef for the map
works and that for the iterator fails?

Quote:
> I don't see a quick workaround in your case. I'm afraid you are in for a
> serious redesign.
> --
> With best wishes,
>     Igor Tandetnik

> "For every complex problem, there is a solution that is simple, neat,
> and wrong." H.L. Mencken

Regards,

~Ajit

Quote:


> > Gurus,

> > I am facing a problem related to STL map. I have following code

> > ///// MyClass.h //////////////////////////////////////////////////
> > #ifndef MY_CLASS_H
> > #define MY_CLASS_H

> > #include <map>
> > using namespace std;

> > class MyClass;

> > typedef map<MyClass, long> MyClassMap;
> > typedef MyClassMap::const_iterator MyClassMapIter;
> > // The program compiles successfully if the above line and all the
> > // references to MyClassMapIter are removed.

> > class MyClass
> > {
> > public:
> >  MyClassMapIter SomeFunc()
> >  {
> >   MyClassMapIter it = m_MyClassMap.begin();
> >   return it;
> >  }

> > protected:
> >  static MyClassMap m_MyClassMap;
> > };

> > #endif //MY_CLASS_H
> > ////////////////////////////////////////////////////////////////

> > ////// EntryFile.cpp ///////////////////////////////////////////
> > #include "MyClass.h"

> > void main()
> > {
> >  MyClass mc;
> >  MyClassMapIter mci = mc.SomeFunc();
> > }
> > ///////////////////////////////////////////////////////////////

> > When I try to compile this code I get following error:

> > ---------Configuration: MapIterator - Win32 Debug-------------
> > Compiling...
> > EntryFile.cpp
> > d:\program files\microsoft visual studio\vc98\include\utility(25) :
> > error C2079: 'first' uses undefined class 'MyClass'
> >         d:\program files\microsoft visual
> > studio\vc98\include\xtree(28) : see reference to class template
> > instantiation 'std::pair<class MyClass const ,long>' being compiled
> >         d:\program files\microsoft visual studio\vc98\include\map(46)
> > : see reference to class template instantiation 'std::_Tree<class
> > MyClass,struct std::pair<class MyClass const ,long>,struct
> > std::map<class MyClass,long,struct std::less<class MyC
> > lass>,class std::allocator<long> >::_Kfn,struct std::less<class
> > MyClass>,class std::allocator<long> >' being compiled
> >         i:\tntd\projects\scpiprojects\mapiterator\myclass.h(10) : see
> > reference to class template instantiation 'std::map<class
> > MyClass,long,struct std::less<class MyClass>,class
> > std::allocator<long> >' being compiled
> > Error executing cl.exe.

> > MapIterator.exe - 1 error(s), 0 warning(s)
> > -------------------------------------------------------------

> > Can anyone please explain me what is meant by this error and how to
> > remove it? I am using VC++ 6.0.

> > Thanks and regards,

> > ~Ajit

> > "There are two ways of constructing a software design: One way is to
> > make it so simple that there are obviously no deficiencies, and the
> > other way is to make it so complicated that there are no obvious
> > deficiencies." - C.A.R. Hoare



Sat, 09 Apr 2005 06:46:20 GMT  
 typedef and iterator

Quote:

> > According to C++ standard 17.4.3.6/2, using an incomplete type as a
> > template parameter for any STL template results in undefined
behavior.

> If this is the case then the statement

> typedef map<MyClass, long> MyClassMap;

> should also give error. But that does not happen. The error is given
> only for the line with the iterator. Why does the typedef for the map
> works and that for the iterator fails?

"Undefined behavior" means anything can happen, including the program
failing at compile time, at run time, or even appearing to work
normally. A particular manifestation depends on implementation details.
You could dig in and figure out why on this particular implementation
the program fails in this particular way, but whatever the reason, your
code is not legal C++ - I suggest you accept it and move on.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken



Sat, 09 Apr 2005 07:00:05 GMT  
 typedef and iterator

Quote:

> try to store MyClass* instead of MyClass - that will assure that the class
> definition for MyClass is not needed at that point.

> Using object pointers rather than objects with stl containers is often a good idea
> because STL does a lot of copying of the stored objects.

std::map already uses pointers internally.  The only container that
copies stored elements internally is std::vector, which has to do so
when it reallocates.

--
Craig Powers
MVP - Visual C++



Sat, 09 Apr 2005 23:33:06 GMT  
 typedef and iterator
On Mon, 21 Oct 2002 14:24:21 -0400, "Igor Tandetnik"

Quote:

>According to C++ standard 17.4.3.6/2, using an incomplete type as a
>template parameter for any STL template results in undefined behavior.

I disagree (although I may be wrong) - I think it is a compiler bug
and nothing to do with his use of the STL. His typedefs shouldn't
cause instantiation of the template types in question. e.g. the
following equivalent example compiles with Comeau C++, but not with
MSVC6:

template <class T>
struct Tem
{
    struct Inner
        {
                T first;
        };

        Inner begin()
        {
                return Inner();
        }

Quote:
};

class C;
typedef Tem<C> MyTem;
typedef MyTem::Inner MyType;

class C
{
public:
    MyType f()
    {
        return myTem.begin();
    }
private:
    static MyTem myTem;

Quote:
};

MyTem C::myTem;

int main()
{
    C c;
    c.f();

Quote:
}

3.2/4 gives a (non normative) list of when a type is required to be
complete, and 14.7.1 says that a type should only be instantiated when
it is referenced in a manner that requires it to be complete. That
only happens to Tem<C> after the full definition of C, where the
static variable is defined (MyTem C::myTem;)

Quote:

>I don't see a quick workaround in your case. I'm afraid you are in for a
>serious redesign.

Does VC.Net compile the above example program? If so, it shouldn't
have any trouble with the OP's original program.

Tom



Sat, 09 Apr 2005 21:54:22 GMT  
 typedef and iterator

Quote:

> Hi,

> try to store MyClass* instead of MyClass - that will assure that the class
> definition for MyClass is not needed at that point.

> Using object pointers rather than objects with stl containers is often a good idea
> because STL does a lot of copying of the stored objects.
> This will give you the problem of keeping track of life time issues - when to call
> delete on such an object pointer. A smart pointer may be a good solution to that.
> But: do not use auto_ptr as this will pass owner ship on copy operations which
> will leave the STL containers with "empty" objects. Have a look at www.boost.org
> instead: shared_ptr.

But wouldn't he have the sample problem instantiating a shared_ptr as he
would instantiating the vector?


Sun, 10 Apr 2005 00:35:16 GMT  
 typedef and iterator
Hi,

try to store MyClass* instead of MyClass - that will assure that the class
definition for MyClass is not needed at that point.

Using object pointers rather than objects with stl containers is often a good idea
because STL does a lot of copying of the stored objects.
This will give you the problem of keeping track of life time issues - when to call
delete on such an object pointer. A smart pointer may be a good solution to that.
But: do not use auto_ptr as this will pass owner ship on copy operations which
will leave the STL containers with "empty" objects. Have a look at www.boost.org
instead: shared_ptr.

HTH,
Sven


Quote:
> Gurus,

> I am facing a problem related to STL map. I have following code

> ///// MyClass.h //////////////////////////////////////////////////
> #ifndef MY_CLASS_H
> #define MY_CLASS_H

> #include <map>
> using namespace std;

> class MyClass;

> typedef map<MyClass, long> MyClassMap;
> typedef MyClassMap::const_iterator MyClassMapIter;
> // The program compiles successfully if the above line and all the
> // references to MyClassMapIter are removed.

> class MyClass
> {
> public:
>  MyClassMapIter SomeFunc()
>  {
>   MyClassMapIter it = m_MyClassMap.begin();
>   return it;
>  }

> protected:
>  static MyClassMap m_MyClassMap;
> };

> #endif //MY_CLASS_H
> ////////////////////////////////////////////////////////////////

> ////// EntryFile.cpp ///////////////////////////////////////////
> #include "MyClass.h"

> void main()
> {
>  MyClass mc;
>  MyClassMapIter mci = mc.SomeFunc();
> }
> ///////////////////////////////////////////////////////////////

> When I try to compile this code I get following error:

> ---------Configuration: MapIterator - Win32 Debug-------------
> Compiling...
> EntryFile.cpp
> d:\program files\microsoft visual studio\vc98\include\utility(25) :
> error C2079: 'first' uses undefined class 'MyClass'
>         d:\program files\microsoft visual
> studio\vc98\include\xtree(28) : see reference to class template
> instantiation 'std::pair<class MyClass const ,long>' being compiled
>         d:\program files\microsoft visual studio\vc98\include\map(46)
> : see reference to class template instantiation 'std::_Tree<class
> MyClass,struct std::pair<class MyClass const ,long>,struct
> std::map<class MyClass,long,struct std::less<class MyC
> lass>,class std::allocator<long> >::_Kfn,struct std::less<class
> MyClass>,class std::allocator<long> >' being compiled
>         i:\tntd\projects\scpiprojects\mapiterator\myclass.h(10) : see
> reference to class template instantiation 'std::map<class
> MyClass,long,struct std::less<class MyClass>,class
> std::allocator<long> >' being compiled
> Error executing cl.exe.

> MapIterator.exe - 1 error(s), 0 warning(s)
> -------------------------------------------------------------

> Can anyone please explain me what is meant by this error and how to
> remove it? I am using VC++ 6.0.

> Thanks and regards,

> ~Ajit

> "There are two ways of constructing a software design: One way is to
> make it so simple that there are obviously no deficiencies, and the
> other way is to make it so complicated that there are no obvious
> deficiencies." - C.A.R. Hoare



Sat, 09 Apr 2005 23:09:46 GMT  
 typedef and iterator


Quote:

>> Hi,

>> try to store MyClass* instead of MyClass - that will assure that the class
>> definition for MyClass is not needed at that point.

>> Using object pointers rather than objects with stl containers is often a good idea
>> because STL does a lot of copying of the stored objects.
>> This will give you the problem of keeping track of life time issues - when to call
>> delete on such an object pointer. A smart pointer may be a good solution to that.
>> But: do not use auto_ptr as this will pass owner ship on copy operations which
>> will leave the STL containers with "empty" objects. Have a look at www.boost.org
>> instead: shared_ptr.

>But wouldn't he have the sample problem instantiating a shared_ptr as he
>would instantiating the vector?

shared_ptr works with incomplete types using the cunning delayed
instantiation trick I first saw in Arglib's grin_ptr. The only thing
that requires a complete type is the shared_ptr(T*) constructor.

Tom



Sun, 10 Apr 2005 01:26:41 GMT  
 typedef and iterator

Quote:

> On Mon, 21 Oct 2002 14:24:21 -0400, "Igor Tandetnik"

>>According to C++ standard 17.4.3.6/2, using an incomplete type as a
>>template parameter for any STL template results in undefined behavior.

> I disagree (although I may be wrong) - I think it is a compiler bug
> and nothing to do with his use of the STL. His typedefs shouldn't
> cause instantiation of the template types in question.

I agree.

 > e.g. the

Quote:
> following equivalent example compiles with Comeau C++, but not with
> MSVC6:
...
> Does VC.NET compile the above example program? If so, it shouldn't
> have any trouble with the OP's original program.

Unfortunately no.  I get:

'Tem<T>::Inner::first' uses undefined class 'C'

Maybe someone who has the 7.1 beta can say if it works for them.



Sun, 10 Apr 2005 00:33:35 GMT  
 typedef and iterator

Quote:

> Maybe someone who has the 7.1 beta can say if it works for them.

Works fine with 7.1.

-cd



Sun, 10 Apr 2005 03:04:45 GMT  
 typedef and iterator

Quote:

> > try to store MyClass* instead of MyClass - that will assure that the
class
> > definition for MyClass is not needed at that point.

> > Using object pointers rather than objects with stl containers is often a
good idea
> > because STL does a lot of copying of the stored objects.

> std::map already uses pointers internally.  The only container that
> copies stored elements internally is std::vector, which has to do so
> when it reallocates.

All stadard C++ library containers store values - i.e. copies.  In map, set,
and list, the value will be embedded in a larger "node" class, while vector
& deque store elements as arrays - but they all store values, not pointers
to values.

-cd



Sun, 10 Apr 2005 03:03:23 GMT  
 typedef and iterator
Hi Craig,


Quote:

> > try to store MyClass* instead of MyClass - that will assure that the class
> > definition for MyClass is not needed at that point.

> > Using object pointers rather than objects with stl containers is often a good
idea
> > because STL does a lot of copying of the stored objects.

> std::map already uses pointers internally.  The only container that
> copies stored elements internally is std::vector, which has to do so
> when it reallocates.

Might that be STL implementation specific?
I looked in the implementation of the STL shipping with VS.Net and found that map
uses this default allocator

allocator<pair<const _Kty, _Ty> > >

with _Kty being the map key in this case class MyClass. And the pair
implementation definitly stores an instance of that type as instance member
"first". So it needs to have the class definition here.

Am I missing something?

Bye,
Sven



Sun, 10 Apr 2005 01:01:25 GMT  
 typedef and iterator


Quote:



> > Maybe someone who has the 7.1 beta can say if it works for them.

> Works fine with 7.1.

I tested that with the same result. So the implementation seems to have changed in
a way that no instance of pair is needed when just used in a typedef ?  To find
the key lines in the changes seems not too easy :)

Bye,
Sven



Sun, 10 Apr 2005 03:36:48 GMT  
 typedef and iterator
Hi,


Quote:

> > Hi,

> > try to store MyClass* instead of MyClass - that will assure that the class
> > definition for MyClass is not needed at that point.

> > Using object pointers rather than objects with stl containers is often a good
idea
> > because STL does a lot of copying of the stored objects.
> > This will give you the problem of keeping track of life time issues - when to
call
> > delete on such an object pointer. A smart pointer may be a good solution to
that.
> > But: do not use auto_ptr as this will pass owner ship on copy operations which
> > will leave the STL containers with "empty" objects. Have a look at
www.boost.org
> > instead: shared_ptr.

> But wouldn't he have the sample problem instantiating a shared_ptr as he
> would instantiating the vector?

I would expect a smart pointer class to store only a pointer of the given template
parameter. So you only need the smart pointer class definition when you use
something like this:

typedef map<shared_ptr<MyClass>, long> MyClassMap;

Bye,
Sven



Sun, 10 Apr 2005 01:30:28 GMT  
 
 [ 19 post ]  Go to page: [1] [2]

 Relevant Pages 

1. typedef and iterator

2. typedef'ing iterators in MSVC's STL (not the HP STL)

3. iterator typedef?

4. Iterator and const Iterator?

5. Typedef structs within typedef structs...

6. Typedef structs within typedef structs...

7. To typedef or not to typedef, that is the question

8. Using find_if returns const iterator, but find returns non const iterator, why?

9. Vector Iterator Error in VC7

10. Bug in MSVC 7.0 (Output Iterator)

11. Tree Iterator...

12. Assigning STL iterator to pointer

 

 
Powered by phpBB® Forum Software