Can I use the map-constructor in a clever way and get rid of this function?

Discussion in 'C++' started by Eric Lilja, Jan 22, 2007.

  1. Eric Lilja

    Eric Lilja Guest

    Hello! Consider this code:

    const char ops[] = {'*', '/', '+', '-'};//, '(', ')' };
    const int input_prio[] = { 3, 3, 1, 1 };//, 100, 0 };
    const int stack_prio[] = { 4, 4, 2, 2 };//, 0, 99 };

    bool GetPriority::is_map_initialized = false;
    map<char, int> GetPriority::stack_priority_map;
    map<char, int> GetPriority::input_priority_map;

    void
    GetPriority::initialize_maps()
    {
    for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    {
    input_priority_map[ops] = input_prio;
    stack_priority_map[ops] = stack_prio;
    }
    }

    What I would like to know if there's a way to initialize my two maps
    (they are static data members of the class GetPriority) using the
    constructor so I can remove initalize_maps() and the flag I check
    before each map use (is_map_initialized)?

    - Eric
    Eric Lilja, Jan 22, 2007
    #1
    1. Advertising

  2. Eric Lilja

    Eric Lilja Guest

    Eric Lilja skrev:

    > Hello! Consider this code:
    >
    > const char ops[] = {'*', '/', '+', '-'};//, '(', ')' };
    > const int input_prio[] = { 3, 3, 1, 1 };//, 100, 0 };
    > const int stack_prio[] = { 4, 4, 2, 2 };//, 0, 99 };
    >
    > bool GetPriority::is_map_initialized = false;
    > map<char, int> GetPriority::stack_priority_map;
    > map<char, int> GetPriority::input_priority_map;
    >
    > void
    > GetPriority::initialize_maps()
    > {
    > for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    > {
    > input_priority_map[ops] = input_prio;
    > stack_priority_map[ops] = stack_prio;
    > }
    > }
    >
    > What I would like to know if there's a way to initialize my two maps
    > (they are static data members of the class GetPriority) using the
    > constructor so I can remove initalize_maps() and the flag I check
    > before each map use (is_map_initialized)?
    >
    > - Eric


    I ended up doing this: Now I have to initializer functions but they are
    only called once each and I don't have to check any flags before
    performing any operations on my maps:

    const char GetPriority::eek:ps[] = {'*', '/', '+', '-'};
    map<char, int>
    GetPriority::input_priority_map(GetPriority::initialize_stack_priority_map());
    map<char, int>
    GetPriority::stack_priority_map(GetPriority::initialize_input_priority_map());


    map<char, int>
    GetPriority::initialize_input_priority_map()
    {
    const int input_prio[] = { 3, 3, 1, 1 };
    map<char, int> m;

    for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    {
    m[ops] = input_prio;
    }

    return m;
    }

    map<char, int>
    GetPriority::initialize_stack_priority_map()
    {
    const int stack_prio[] = { 4, 4, 2, 2 };
    map<char, int> m;

    for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    {
    m[ops] = stack_prio;
    }

    return m;
    }

    - Eric
    Eric Lilja, Jan 22, 2007
    #2
    1. Advertising

  3. Eric Lilja

    Ondra Holub Guest

    Eric Lilja napsal:
    > Hello! Consider this code:
    >
    > const char ops[] = {'*', '/', '+', '-'};//, '(', ')' };
    > const int input_prio[] = { 3, 3, 1, 1 };//, 100, 0 };
    > const int stack_prio[] = { 4, 4, 2, 2 };//, 0, 99 };
    >
    > bool GetPriority::is_map_initialized = false;
    > map<char, int> GetPriority::stack_priority_map;
    > map<char, int> GetPriority::input_priority_map;
    >
    > void
    > GetPriority::initialize_maps()
    > {
    > for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    > {
    > input_priority_map[ops] = input_prio;
    > stack_priority_map[ops] = stack_prio;
    > }
    > }
    >
    > What I would like to know if there's a way to initialize my two maps
    > (they are static data members of the class GetPriority) using the
    > constructor so I can remove initalize_maps() and the flag I check
    > before each map use (is_map_initialized)?
    >
    > - Eric


    Yes, you can, but I am not sure whether it is better solution:

    #include <map>

    typedef
    std::pair<char, int> p;

    const p init_data[] =
    {
    p('*', 3),
    p('/', 3),
    p('+', 1),
    p('-', 1)
    };

    const size_t LEN = sizeof(init_data) / sizeof(init_data[0]);

    int main()
    {
    std::map<char, int> stack_priority_map(
    &init_data[0],
    &init_data[LEN]
    );
    };
    Ondra Holub, Jan 22, 2007
    #3
  4. Eric Lilja

    Eric Lilja Guest

    Eric Lilja skrev:

    > Eric Lilja skrev:
    >
    > > Hello! Consider this code:
    > >
    > > const char ops[] = {'*', '/', '+', '-'};//, '(', ')' };
    > > const int input_prio[] = { 3, 3, 1, 1 };//, 100, 0 };
    > > const int stack_prio[] = { 4, 4, 2, 2 };//, 0, 99 };
    > >
    > > bool GetPriority::is_map_initialized = false;
    > > map<char, int> GetPriority::stack_priority_map;
    > > map<char, int> GetPriority::input_priority_map;
    > >
    > > void
    > > GetPriority::initialize_maps()
    > > {
    > > for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    > > {
    > > input_priority_map[ops] = input_prio;
    > > stack_priority_map[ops] = stack_prio;
    > > }
    > > }
    > >
    > > What I would like to know if there's a way to initialize my two maps
    > > (they are static data members of the class GetPriority) using the
    > > constructor so I can remove initalize_maps() and the flag I check
    > > before each map use (is_map_initialized)?
    > >
    > > - Eric

    >
    > I ended up doing this: Now I have to initializer functions but they are
    > only called once each and I don't have to check any flags before
    > performing any operations on my maps:
    >
    > const char GetPriority::eek:ps[] = {'*', '/', '+', '-'};
    > map<char, int>
    > GetPriority::input_priority_map(GetPriority::initialize_stack_priority_map());
    > map<char, int>
    > GetPriority::stack_priority_map(GetPriority::initialize_input_priority_map());
    >
    >
    > map<char, int>
    > GetPriority::initialize_input_priority_map()
    > {
    > const int input_prio[] = { 3, 3, 1, 1 };
    > map<char, int> m;
    >
    > for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    > {
    > m[ops] = input_prio;
    > }
    >
    > return m;
    > }
    >
    > map<char, int>
    > GetPriority::initialize_stack_priority_map()
    > {
    > const int stack_prio[] = { 4, 4, 2, 2 };
    > map<char, int> m;
    >
    > for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    > {
    > m[ops] = stack_prio;
    > }
    >
    > return m;
    > }
    >
    > - Eric


    I meant two initializer functions and I've found and fixed the bug
    where I call the wrong one for the maps. :)

    - Eric
    Eric Lilja, Jan 22, 2007
    #4
  5. Eric Lilja

    Kai-Uwe Bux Guest

    Eric Lilja wrote:

    > Hello! Consider this code:
    >
    > const char ops[] = {'*', '/', '+', '-'};//, '(', ')' };
    > const int input_prio[] = { 3, 3, 1, 1 };//, 100, 0 };
    > const int stack_prio[] = { 4, 4, 2, 2 };//, 0, 99 };
    >
    > bool GetPriority::is_map_initialized = false;
    > map<char, int> GetPriority::stack_priority_map;
    > map<char, int> GetPriority::input_priority_map;
    >
    > void
    > GetPriority::initialize_maps()
    > {
    > for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    > {
    > input_priority_map[ops] = input_prio;
    > stack_priority_map[ops] = stack_prio;
    > }
    > }
    >
    > What I would like to know if there's a way to initialize my two maps
    > (they are static data members of the class GetPriority) using the
    > constructor so I can remove initalize_maps() and the flag I check
    > before each map use (is_map_initialized)?


    This is one of the few cases where I would consider inheriting from standard
    containers:

    #include <map>

    const char ops [] = {'*', '/', '+', '-'};//, '(', ')' };
    const int input_prio[] = { 3, 3, 1, 1 };//, 100, 0 };
    const int stack_prio[] = { 4, 4, 2, 2 };//, 0, 99 };

    class GetPriority {

    struct stack_priority_map : public std::map<char,int> {

    stack_priority_map ( void ) {
    for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    {
    this->operator[]( ops ) = stack_prio;
    }
    }

    };

    static stack_priority_map stack_priority;

    struct input_priority_map : public std::map<char,int> {

    input_priority_map ( void ) {
    for (unsigned int i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i)
    {
    this->operator[]( ops ) = input_prio;
    }
    }

    };

    static input_priority_map input_priority;

    public:

    // here you can use stack_priority and input_priority at will.
    // E.g.:
    int stack ( char c ) {
    return ( stack_priority[c] );
    }

    };

    GetPriority::stack_priority_map GetPriority::stack_priority;
    GetPriority::input_priority_map GetPriority::input_priority;

    #include <iostream>

    int main ( void ) {
    GetPriority gp;
    std::cout << gp.stack( '*' ) << '\n';
    }


    Of course, if you also have static variables whose initialization depends on
    those maps, you might need to do some additional work to ensure proper
    order of initialization. E.g.: instead of a variable input_priority, you
    could have a function:

    static
    int input_priority ( char c ) {
    static input_priority_map dummy;
    return ( dummy[c] );
    }


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jan 22, 2007
    #5
    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. Replies:
    14
    Views:
    661
  2. Holger
    Replies:
    4
    Views:
    276
    Holger
    Oct 9, 2008
  3. WP
    Replies:
    2
    Views:
    232
    Daniel Pitts
    Oct 30, 2008
  4. dr.oktopus

    efficient or clever way

    dr.oktopus, Jun 6, 2011, in forum: C Programming
    Replies:
    7
    Views:
    314
    Anand Hariharan
    Jun 9, 2011
  5. Cyril.Liu
    Replies:
    3
    Views:
    446
    Clifford Heath
    Aug 20, 2010
Loading...

Share This Page