Archived

This forum has been archived. Please start a new discussion on GitHub.

C++ mapping for a dictionary with an enum as the key

So I have an Ice file that can be boiled down to this:
enum WorldAction {
        Click, Drag, Pop, Merge, PopOrMerge
    };
    
    dictionary<WorldAction, int> WorldActionCount;

In C++, this turns into
enum WorldAction
{
Click,
Drag,
Pop,
Merge,
PopOrMerge
};

typedef ::std::map< ::echoes::WorldAction, ::Ice::Int> WorldActionCount;

If I try to access the members of WorldActionCount in my C++ code, it won't compile. Here's a dummy server-side implementation of one such method (everything is in the "echoes" namespace):
void EventListenerI::userActions(::Ice::Int msec, ::Ice::Int count,
		const ::echoes::WorldActionCount& allActions,
		const ::echoes::WorldActionCount& consActions,
		const ::Ice::Current& __ctx) {

		std::cout << allActions[::echoes::Click] << std::endl;
}

If I try to compile this, I get the following error:
..\src\EventListenerI.cpp(100) : error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const echoes::WorldActionCount' (or there is no acceptable conversion)
C:\Program Files\Microsoft Visual Studio 9.0\VC\include\map(167): could be 'int &std::map<_Kty,_Ty>::operator [](const echoes::WorldAction &)'
with
[
_Kty=echoes::WorldAction,
_Ty=Ice::Int
]
while trying to match the argument list '(const echoes::WorldActionCount, echoes::WorldAction)'

What's going on? Shouldn't this work?

Thanks,

MEF

Comments

  • marc
    marc Florida
    You can't use operator[] on a const std::map, since it might insert an element if it does not already exist. Have a look at:

    map<Key, Data, Compare, Alloc>
    [3] Since operator[] might insert a new element into the map, it can't possibly be a const member function. Note that the definition of operator[] is extremely simple: m[k] is equivalent to (*((m.insert(value_type(k, data_type()))).first)).second. Strictly speaking, this member function is unnecessary: it exists only for convenience.
  • marc wrote: »
    You can't use operator[] on a const std::map, since it might insert an element if it does not already exist.

    Right, that makes sense. But the function header I showed is exactly the one that Ice generates for the following method signature:
    void userActions (int msec, int count, WorldActionCount allActions, WorldActionCount consActions);
    

    So it's not really possible to get rid of the "const" on the map except by casting it away, right? I guess we'll just need to use some other method of accessing the members of the map ...

    MEF
  • marc
    marc Florida
    mefoster wrote: »
    Right, that makes sense. But the function header I showed is exactly the one that Ice generates for the following method signature:
    void userActions (int msec, int count, WorldActionCount allActions, WorldActionCount consActions);
    

    So it's not really possible to get rid of the "const" on the map except by casting it away, right? I guess we'll just need to use some other method of accessing the members of the map ...

    MEF

    You can use allActions.find(::echoes::Click). In general, you have to be careful with using operator[], because of the side effects mentioned in the footnote I quoted above.