Map problem

Discussion in 'C++' started by tech, Apr 11, 2008.

  1. tech

    tech Guest

    Hi, I want to create a map of named events from a const array.

    eg std::map<std::string, HANDLE> this needs to be intialised so that

    initially it will be contain the names of the all the events with a
    NULL handle then
    i can do the following

    std::map<std::string, HANDLE> Events;
    std::map<std::string, HANDLE>::iterator it;

    const std::string[] { "EventName1", "EventName2", "EventName3"};

    it = Events.begin();

    while (it != Events.end())
    {
    Events[it->first] = CreateEvent(NULL,FALSE,FALSE, it->first.c_str())
    ++it;
    }


    So i f i ever need a new event all i need to do is add it to the array
    and the event will be created
    managed, destroyed just using the map.

    However do i use the string array to initalise the map keys however?
     
    tech, Apr 11, 2008
    #1
    1. Advertising

  2. tech

    Jim Langston Guest

    tech wrote:
    > Hi, I want to create a map of named events from a const array.
    >
    > eg std::map<std::string, HANDLE> this needs to be intialised so that
    >
    > initially it will be contain the names of the all the events with a
    > NULL handle then
    > i can do the following
    >
    > std::map<std::string, HANDLE> Events;
    > std::map<std::string, HANDLE>::iterator it;
    >
    > const std::string[] { "EventName1", "EventName2", "EventName3"};


    I think you meant to give this a name. Something Like:
    const std::string EventNames[] { "EventName1", "EventName2", "EventName3"};

    > it = Events.begin();
    >
    > while (it != Events.end())
    > {
    > Events[it->first] = CreateEvent(NULL,FALSE,FALSE, it->first.c_str())
    > ++it;
    > }
    >
    >
    > So i f i ever need a new event all i need to do is add it to the array
    > and the event will be created
    > managed, destroyed just using the map.
    >
    > However do i use the string array to initalise the map keys however?


    Simplest would be something like:

    for ( int i = 0; i < sizeof( EventNames ) / sizeof( EvenNames[0] ); ++i )
    Events[EventNames] = NULL;

    the sizeof( Eventnames ) / sizeof( EventNames[0]] may be a little off. Thsi
    just is to determine how many names are in the array.

    But really, for a constant array of text I'd just go with a char*[]

    const char* EventNames[] = { "EventName1", "EventName2", "EventName3"};

    Notice that this isn't using C style char arrays, but an array of character
    pointers.



    --
    Jim Langston
     
    Jim Langston, Apr 11, 2008
    #2
    1. Advertising

  3. tech

    Guest

    On 11 Apr., 12:48, "Jim Langston" <> wrote:
    > tech wrote:
    > > Hi, I want to create a map of named events from a const array.

    >
    > > However do i use the string array to initalise the map keys however?

    >
    > Simplest would be something like:
    >
    > for ( int i = 0; i < sizeof( EventNames ) / sizeof( EvenNames[0] ); ++i )
    > Events[EventNames] = NULL;
    >


    Alternatively, you may change the EventNames[] array to
    std::pair<std::string, HANDLE>:

    typedef std::pair<std::string, HANDLE> Pair;

    Pair EventNames[] = {
    Pair( "EventName1", 0 ),
    Pair( "EventName2", 0 ),
    ...
    };

    This looks more ugly at first (the typedef enhances usability a
    little). However, you now can do the initialization like this:

    std::map<std::string, HANDLE> Events(
    &EventNames[0],
    &EventNames[ sizeof EventNames / sizeof( Pair ) ]
    );


    This avoids explicit loops and can be used in a constructor
    initializer list. Its a mere matter of taste.

    best,

    Michael
     
    , Apr 11, 2008
    #3
  4. tech wrote:
    > Hi, I want to create a map of named events from a const array.
    >
    > eg std::map<std::string, HANDLE> this needs to be intialised so that
    >
    > initially it will be contain the names of the all the events with a
    > NULL handle then
    > i can do the following
    >
    > std::map<std::string, HANDLE> Events;
    > std::map<std::string, HANDLE>::iterator it;
    >
    > const std::string[] { "EventName1", "EventName2", "EventName3"};


    const std::string eventNames[] = { "EventName1", "EventName2", "EventName3"};

    > it = Events.begin();
    >
    > while (it != Events.end())
    > {
    > Events[it->first] = CreateEvent(NULL,FALSE,FALSE, it->first.c_str())


    Since 'it' already refers to the pair of std::string,HANDLE you want to
    access in the map, just use:
    it->second = ...
    instead of
    Events[it->first] = ...

    > ++it;
    > }


    But because you want to fill the map with the array, you would want to loop
    over the array and not over the map content, as Jim Langston wrote.

    >
    > So i f i ever need a new event all i need to do is add it to the array
    > and the event will be created
    > managed, destroyed just using the map.


    Wrong. The map doesn't know how to destroy the events. You will have to
    loop over the map elements and call the right function to destroy the
    events as documented with the CreateEvent function.
    The map will only destroy, and release memory for, the HANDLE.

    --
    Thomas
    http://www.netmeister.org/news/learn2quote.html
    There are no bugs, and they have been fixed!
     
    Thomas J. Gritzan, Apr 11, 2008
    #4
  5. tech

    Jerry Coffin Guest

    In article <6e90926f-18bc-42ac-bac6-16e590038a75
    @x41g2000hsb.googlegroups.com>, says...
    > Hi, I want to create a map of named events from a const array.
    >
    > eg std::map<std::string, HANDLE> this needs to be intialised so that
    >
    > initially it will be contain the names of the all the events with a
    > NULL handle then
    > i can do the following
    >
    > std::map<std::string, HANDLE> Events;
    > std::map<std::string, HANDLE>::iterator it;
    >
    > const std::string[] { "EventName1", "EventName2", "EventName3"};
    >
    > it = Events.begin();
    >
    > while (it != Events.end())
    > {
    > Events[it->first] = CreateEvent(NULL,FALSE,FALSE, it->first.c_str())
    > ++it;
    > }
    >
    >
    > So i f i ever need a new event all i need to do is add it to the array
    > and the event will be created
    > managed, destroyed just using the map.
    >
    > However do i use the string array to initalise the map keys however?


    I'd start by writing a wrapper class for the events:

    // warning: untested code.
    class event {
    HANDLE ev;
    public:
    // You usually don't want to name events unless you're sharing them
    // across process boundaries.
    event() : ev(CreateEvent(NULL, FALSE, FALSE, NULL) {}

    // haven't thought a lot about this -- might cause problem when copying
    // an event. They're really more "identity" than "value" objects.
    ~event() { CloseHandle(ev); }

    DWORD wait(DWORD time = INFINITE) {
    return WaitForSingleObject(ev, time);
    }
    };

    Then you can put events into your map a bit more directly:

    std::map<std::string, event> events;
    char const *names[] = {"Event1", "Event2", "Event3"};

    #define elements(x) (sizeof(x)/sizeof(x[0]))

    for (int i=0; i<elements(names); ++i)
    events.insert(std::make_pair(names, event()));

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Apr 12, 2008
    #5
  6. Jerry Coffin wrote:
    [putting an Windows event HANDLE into a std::map]
    > I'd start by writing a wrapper class for the events:
    >
    > // warning: untested code.
    > class event {
    > HANDLE ev;
    > public:
    > // You usually don't want to name events unless you're sharing them
    > // across process boundaries.
    > event() : ev(CreateEvent(NULL, FALSE, FALSE, NULL) {}
    >
    > // haven't thought a lot about this -- might cause problem when copying
    > // an event. They're really more "identity" than "value" objects.
    > ~event() { CloseHandle(ev); }
    >
    > DWORD wait(DWORD time = INFINITE) {
    > return WaitForSingleObject(ev, time);
    > }
    > };
    >
    > Then you can put events into your map a bit more directly:
    >
    > std::map<std::string, event> events;
    > char const *names[] = {"Event1", "Event2", "Event3"};
    >
    > #define elements(x) (sizeof(x)/sizeof(x[0]))
    >
    > for (int i=0; i<elements(names); ++i)
    > events.insert(std::make_pair(names, event()));
    >


    Remember the Rule of three? The standard container require the elements to
    be copyable.

    One could use a std::shared_ptr for this.

    --
    Thomas
    http://www.netmeister.org/news/learn2quote.html
    The pedants here will shout "int main(void)" but I'll just whisper it.
    --Bob Wightman in comp.lang.c
     
    Thomas J. Gritzan, Apr 12, 2008
    #6
  7. tech

    Jerry Coffin Guest

    In article <ftqnga$ads$>,
    says...

    [ ... ]

    > > // haven't thought a lot about this -- might cause problem when copying
    > > // an event. They're really more "identity" than "value" objects.


    [ ... ]

    > Remember the Rule of three? The standard container require the elements to
    > be copyable.
    >
    > One could use a std::shared_ptr for this.


    Obviously I remembered that they need to be copyable, but didn't go much
    beyond that (e.g. to making the code work). :)

    You could use a shared_ptr, or you could use DuplicateHandle. A
    shared_ptr is probably more idiomatic C++, while DuplicateHandle is
    probably more idiomatic Win32. Most like a shared_ptr is faster though
    (since it avoids an OS call).

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Apr 12, 2008
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. alex
    Replies:
    1
    Views:
    651
    Lau Lei Cheong
    Feb 4, 2005
  2. Matthias Hildebrand
    Replies:
    5
    Views:
    7,982
    krogers
    Mar 20, 2012
  3. Vlad
    Replies:
    0
    Views:
    362
  4. Patrick Guio
    Replies:
    6
    Views:
    3,210
    chris
    Oct 20, 2004
  5. Erik Arner
    Replies:
    0
    Views:
    1,313
    Erik Arner
    Nov 2, 2004
Loading...

Share This Page