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

E

Eric Lilja

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
 
E

Eric Lilja

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
 
O

Ondra Holub

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]
);
};
 
E

Eric Lilja

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
 
K

Kai-Uwe Bux

Eric said:
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
 

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

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top