DEVELOP > c-Plus-Plus > Can I use the map-constructor in a clever way and get rid of this function?
| Topic: |
DEVELOP > c-Plus-Plus |
| User: |
"Eric Lilja" |
| Date: |
22 Jan 2007 09:06:09 AM |
| Object: |
Can I use the map-constructor in a clever way and get rid of this function? |
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[i]] = input_prio[i];
stack_priority_map[ops[i]] = stack_prio[i];
}
}
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
.
|
|
| User: "Ondra Holub" |
|
| Title: Re: Can I use the map-constructor in a clever way and get rid of this function? |
22 Jan 2007 09:24:35 AM |
|
|
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[i]] = input_prio[i];
stack_priority_map[ops[i]] = stack_prio[i];
}
}
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]
);
};
.
|
|
|
|
| User: "Eric Lilja" |
|
| Title: Re: Can I use the map-constructor in a clever way and get rid of this function? |
22 Jan 2007 09:23:26 AM |
|
|
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[i]] = input_prio[i];
stack_priority_map[ops[i]] = stack_prio[i];
}
}
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::ops[] = {'*', '/', '+', '-'};
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[i]] = input_prio[i];
}
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[i]] = stack_prio[i];
}
return m;
}
- Eric
.
|
|
|
| User: "Eric Lilja" |
|
| Title: Re: Can I use the map-constructor in a clever way and get rid of this function? |
22 Jan 2007 09:26:05 AM |
|
|
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[i]] = input_prio[i];
stack_priority_map[ops[i]] = stack_prio[i];
}
}
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::ops[] = {'*', '/', '+', '-'};
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[i]] = input_prio[i];
}
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[i]] = stack_prio[i];
}
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
.
|
|
|
|
|
| User: "Kai-Uwe Bux" |
|
| Title: Re: Can I use the map-constructor in a clever way and get rid of this function? |
22 Jan 2007 09:39:01 AM |
|
|
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[i]] = input_prio[i];
stack_priority_map[ops[i]] = stack_prio[i];
}
}
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[i] ) = stack_prio[i];
}
}
};
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[i] ) = input_prio[i];
}
}
};
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
.
|
|
|
|

|
Related Articles |
|
|