Storing a ValueType inside an STL map?

G

Guest

Hello,

I'm using Managed C++ in .NET 2003. I'm trying to map integers to Enums
inside an STL map container, but I cannot get it to compile. This might be a
simple question, and I'm sure I'm missing something, but I haven't used STL a
lot inside MC++. Here's my code:

#include <map>
#include <vcclr.h>

public __gc class Managed
{
public:
__value enum MyEnum
{
Value1,
Value2,
Value3
};

typedef std::map<int, gcroot<MyEnum*> > MyMap;
static MyMap* _myMap = new MyMap();

Managed()
{
_myMap->insert(MyMap::value_type(123, __box(MyEnum::Value1)));
}
};

int _tmain()
{
return 0;
}


The compiler errors I'm getting are as follows:


C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\gcroot.h(61)
: error C2665: 'System::Runtime::InteropServices::GCHandle::Alloc' : none of
the 2 overloads can convert parameter 1 from type 'Managed::MyEnum __gc *'
StlMapWithMgdEnum.cpp(0): could be
'System::Runtime::InteropServices::GCHandle
System::Runtime::InteropServices::GCHandle::Alloc(System::Object __gc *)'
while trying to match the argument list '(Managed::MyEnum __gc *)'
C:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\gcroot.h(60) : while compiling class-template member
function 'gcroot<T>::gcroot(Managed::MyEnum __gc *)'
with
[
T=Managed::MyEnum __gc *
]
C:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\utility(51) : see reference to class template instantiation
'gcroot<T>' being compiled
with
[
T=Managed::MyEnum __gc *
]
StlMapWithMgdEnum.cpp(19) : see reference to class template
instantiation 'std::pair<_Ty1,_Ty2>' being compiled
with
[
_Ty1=const int,
_Ty2=gcroot<Managed::MyEnum __gc *>
]
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\gcroot.h(63)
: error C2228: left of '.ToInt32' must have class/struct/union type

Is it possible to do what I'm attempting here? I want to use std::map for
the type safety, but do I need to punt and resort to using a
System::Collections::Hashtable and __box everything?

Thanks!
 
G

Gary Chang[MSFT]

Hi Whitney,

Thank you posting!

It seems the errors are caused by the following code:
typedef std::map<int, gcroot<MyEnum*> > MyMap;

The gcroot<T> template needs the type T is a managed pointer type which
points to a __gc type object. Since your MyEnum is a value type object,
you need to inbox its pointer before using the gcroot<T> template to wrap
it:

...
__value enum MyEnum
{
Value1,
Value2,
Value3
};

typedef __box MyEnum* pMyEnum;

typedef std::map<int, gcroot<pMyEnum> > MyMap;
...

Wish the above sample code helps, thanks!


Best regards,

Gary Chang
Microsoft Community Support
======================================================
PLEASE NOTE the newsgroup SECURE CODE and PASSWORD will be updated at 9:00
AM PST, February 14, 2006. Please complete a re-registration process by
entering the secure code mmpng06 when prompted. Once you have entered the
secure code mmpng06, you will be able to update your profile and access the
partner newsgroups.
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Thank you Gary, that solved my problem!
--
Whitney Kew
Software Engineer


"Gary Chang[MSFT]" said:
Hi Whitney,

Thank you posting!

It seems the errors are caused by the following code:
typedef std::map<int, gcroot<MyEnum*> > MyMap;

The gcroot<T> template needs the type T is a managed pointer type which
points to a __gc type object. Since your MyEnum is a value type object,
you need to inbox its pointer before using the gcroot<T> template to wrap
it:

...
__value enum MyEnum
{
Value1,
Value2,
Value3
};

typedef __box MyEnum* pMyEnum;

typedef std::map<int, gcroot<pMyEnum> > MyMap;
...

Wish the above sample code helps, thanks!


Best regards,

Gary Chang
Microsoft Community Support
======================================================
PLEASE NOTE the newsgroup SECURE CODE and PASSWORD will be updated at 9:00
AM PST, February 14, 2006. Please complete a re-registration process by
entering the secure code mmpng06 when prompted. Once you have entered the
secure code mmpng06, you will be able to update your profile and access the
partner newsgroups.
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Gary Chang[MSFT]

You are welcome, Whitney. :)

Have a nice day!

Best regards,

Gary Chang
Microsoft Community Support
======================================================
PLEASE NOTE the newsgroup SECURE CODE and PASSWORD will be updated at 9:00
AM PST, February 14, 2006. Please complete a re-registration process by
entering the secure code mmpng06 when prompted. Once you have entered the
secure code mmpng06, you will be able to update your profile and access the
partner newsgroups.
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
H

Holger Grund

Whitney Kew said:
__value enum MyEnum
{
Value1,
Value2,
Value3
};

typedef std::map<int, gcroot<MyEnum*> > MyMap;

You do not need gcroot here. You can the boxed version of the value
type. This is almost always pure overhead. Value types can perfectly
exist outside the garbage-collected heap (that's actually why they exist).

Hence, it is perfectly valid to write
std::map said:
_myMap->insert(MyMap::value_type(123, __box(MyEnum::Value1)));
which would, of course, also mean that you would remove __box()

-hg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top