pointer is std:map - broke in port from VS6 to .NET - A little Help?

  • Thread starter Thread starter Dan Trowbridge
  • Start date Start date
D

Dan Trowbridge

Hi everyone,

In my attempt to port code from VS 6.0 to VS.NET I had some code break along
the way, mostly due to not adhereing closely to the C++ standard. This may
be another instance but I can't think of a good fix, or even why it broke.

The problem

In one of my CFormView derived classes I have a member variable of the
type...

std::map<geom_base *, mass_props> mass_prop_map;

which I populate like...

mass_prop_map.insert(pair<geom_base *, mass_props>(af, mass_props(volume,
mass, weight, surface_area)));
where "mass_props" is a class whose constructor is called during the
"insert" shown above.
and "af" is a pointer to a class object that is derived from "geom_base"

I use the map to populated controls on the view with data from only certain
geom_base derived objects (ones that meet certain critera)

The .NET compiler doesn't like the std::map<geom_base *, mass_props>
mass_prop_map; variable declaration - it wouldn't compile.
If I change "geom_base *" to "geom_base" (and change the insert to reflect
the change) it will compile OK but in execution it will force a copy to be
made of the "af" object, which is quite huge and I don't need a local copy
inside the CFormView derived class, it would be a waste.

Am I breaking the rules again by using a pointer as a key type inside a
std::map? I don't see anything in the online-docs (MSDN) that says you
can't. Again, this worked fine inside VS 6.0.
Does anyone have any idea what is wrong and what is a work-around?

In the words of James Ingram: "I did my best but I guess my best wasn't
goooooood enough"
 
Pointer as a key-type for std::map is perfectly legal. Can you post a small
but complete example that illustrates the error you're running into?

-cd
 
Carl,

Well I did it in a seperate project and, don't you know it, it works fine
with the simple classes. Here is my sample code:
class fred
{
public:
fred() {};
virtual ~fred() {};
};
class pebbles : public fred
{
public:
pebbles() : fred() {};
virtual ~pebbles() {};
};
class barney
{
public:
barney() {};
virtual ~barney() {};
};
int main(int argc, char* argv[])
{
std::map<fred *, barney> flintstones;
pebbles * pebbles_pointer = new pebbles();
flintstones.insert( pair<fred *, barney >( pebbles_pointer,
barney() ) );
std::map<fred *, barney>::iterator fi;
fi = flintstones.find(pebbles_pointer);
return(0);
}

Since I first posted this I have changed the std::map<geom_base *,
calc_mass_props> usage to deque<pair< geom_base *, calc_mass_props> > and
then wrote my own "find" code to look up things I needed. This new method
works good but required a little extra coding. After recieving your post I
went back and changed everything back to std::map<geom_base *, mass_props>
and things are still not compiling. So I have a working version of the code
by using the "deque method" but it would still be nice to know why the more
eligant "map method" didn't work. If you care to consider what may be
wrong, the following is the error codes that the compiler gives me but don't
knock yourself out over it since I can always sue the "deque method" (but is
does sort-of make you want to stear clear of std::map :-) )...

(NOTE: In my original post I said the "data" member of the map was of type
"mass_props" in reallity it is of type "calc_mass_props". I change the name
in the original post because I wanted to avoid confusion becasue I was
afraid that "calc_mass_props(volume, mass, weight, surface_area)" could look
like a function call and not a constructor in the line:
mass_prop_map.insert( pair<geom_base *, calc_mass_props >( af,
calc_mass_props(volume, mass, weight, surface_area) ) );
The error codes provided below have the original(true) class names (i.e.
"calc_mass_props" not "mass_props")

geom_audit_view.cpp
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xtree(1133) :
error C2061: syntax error : identifier '_Wherenode'
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xtree(1130) :
while compiling class-template member function
'std::_Tree<_Traits>::_Nodeptr
std::_Tree<_Traits>::_Buynode(std::_Tree<_Traits>::_Nodeptr,std::_Tree<_Trai
ts>::_Nodeptr,std::_Tree<_Traits>::_Nodeptr,const
std::_Tree<_Traits>::value_type &,char)'
with
[
_Traits=std::_Tmap_traits<geom_base *,calc_mass_props,std::less<geom_base
*>,std::allocator<std::pair<geom_base *const ,calc_mass_props>>,false>
]
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\map(77) : see
reference to class template instantiation 'std::_Tree<_Traits>' being
compiled
with
[
_Traits=std::_Tmap_traits<geom_base *,calc_mass_props,std::less<geom_base
*>,std::allocator<std::pair<geom_base *const ,calc_mass_props>>,false>
]
c:\dan\cwork\sabdev\geom_audit_view.h(91) : see reference to class template
instantiation 'std::map<_Kty,_Ty>' being compiled
with
[
_Kty=geom_base *,
_Ty=calc_mass_props
]
 
Certainly an odd error message you're getting. Without digging into it, the
one thing that pops to mind is that maybe there's a macro in the "real"
project that's clobbering part of the std::map implementation? That kind of
thing can be incredibly hard to track down, but it is possible.

Preprocess one of your files (using cl /P) and then try to compile the
pre-processed output. Assuming you get the same error, you can then examine
that single linear file to see if there's something that doesn't look right
due to a macro, etc. Still tedious, but sometimes an effective strategy.

-cd

Dan said:
Carl,

Well I did it in a seperate project and, don't you know it, it works
fine with the simple classes. Here is my sample code:
class fred
{
public:
fred() {};
virtual ~fred() {};
};
class pebbles : public fred
{
public:
pebbles() : fred() {};
virtual ~pebbles() {};
};
class barney
{
public:
barney() {};
virtual ~barney() {};
};
int main(int argc, char* argv[])
{
std::map<fred *, barney> flintstones;
pebbles * pebbles_pointer = new pebbles();
flintstones.insert( pair<fred *, barney >( pebbles_pointer,
barney() ) );
std::map<fred *, barney>::iterator fi;
fi = flintstones.find(pebbles_pointer);
return(0);
}

Since I first posted this I have changed the std::map<geom_base *,
calc_mass_props> usage to deque<pair< geom_base *, calc_mass_props> >
and then wrote my own "find" code to look up things I needed. This
new method works good but required a little extra coding. After
recieving your post I went back and changed everything back to
std::map<geom_base *, mass_props> and things are still not compiling.
So I have a working version of the code by using the "deque method"
but it would still be nice to know why the more eligant "map method"
didn't work. If you care to consider what may be wrong, the
following is the error codes that the compiler gives me but don't
knock yourself out over it since I can always sue the "deque method"
(but is does sort-of make you want to stear clear of std::map :-)
)...

(NOTE: In my original post I said the "data" member of the map was of
type "mass_props" in reallity it is of type "calc_mass_props". I
change the name in the original post because I wanted to avoid
confusion becasue I was afraid that "calc_mass_props(volume, mass,
weight, surface_area)" could look like a function call and not a
constructor in the line: mass_prop_map.insert( pair<geom_base *,
calc_mass_props >( af, calc_mass_props(volume, mass, weight,
surface_area) ) );
The error codes provided below have the original(true) class names
(i.e. "calc_mass_props" not "mass_props")

geom_audit_view.cpp
c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\xtree(1133) : error C2061: syntax error : identifier
'_Wherenode'
c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\xtree(1130) : while compiling class-template member
function 'std::_Tree<_Traits>::_Nodeptr
std::_Tree said:
ts>::_Nodeptr,std::_Tree<_Traits>::_Nodeptr,const
std::_Tree<_Traits>::value_type &,char)'
with
[
_Traits=std::_Tmap_traits<geom_base
*,calc_mass_props,std::less<geom_base
*>,std::allocator<std::pair<geom_base *const ,calc_mass_props>>,false>
]
c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\map(77) : see reference to class template
instantiation 'std::_Tree<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<geom_base
*,calc_mass_props,std::less<geom_base
*>,std::allocator<std::pair<geom_base *const ,calc_mass_props>>,false>
]
c:\dan\cwork\sabdev\geom_audit_view.h(91) : see reference to class
template instantiation 'std::map<_Kty,_Ty>' being compiled
with
[
_Kty=geom_base *,
_Ty=calc_mass_props
]

"Carl Daniel [VC++ MVP]"
Pointer as a key-type for std::map is perfectly legal. Can you post
a small but complete example that illustrates the error you're
running into?

-cd
 
Back
Top