Why is it no possible to fill a static map outside of a block

U

utab

Dear all,

in a class definition

class X{

private:
static map< string , map<string, int> > word_map;
static void initialize();
};

and in the implementation file, I may fill out the map inside the
function block not outside any function block. I asked this question
before and got a reply advicing to put those lines in an initializer
function. This works fine but I wondered why I could not define and
initiliaze outside the function block. As

word_map["try"].insert(make_pair("try",1));

and the entries outside any of the functions. This is sth related to
static but could not figure that out.

thanks
 
U

utab

I forgot to write I type

map< string , map<string, int> > word_map;

first.

utab schreef:
 
U

utab

I forgot to write I type

map< string , map<string, int> > word_map;

first.

utab schreef:
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

Dear all,

in a class definition

class X{

private:
static map< string , map<string, int> > word_map;
static void initialize();

};

and in the implementation file, I may fill out the map inside the
function block not outside any function block. I asked this question
before and got a reply advicing to put those lines in an initializer
function. This works fine but I wondered why I could not define and
initiliaze outside the function block. As

word_map["try"].insert(make_pair("try",1));

and the entries outside any of the functions. This is sth related to
static but could not figure that out.

Code outside a function-block is never executed, it's just information
about what should be known when the application starts. But the map
does not exist before then.
 
U

utab

Thanks, but still not clear what is exactly "know".

It is already empty so that I would like to fill that out.
Code outside a function-block is never executed, it's just information

But if I give a integral type I can do

int X::value=3;

Right, so this means that this is executed to associate the memory
location of value to 3
There is a difference in map implementation I guess, but my knowledge
is not that sharp.
 
U

utab

Thanks, but still not clear what is exactly "know".

It is already empty so that I would like to fill that out.
Code outside a function-block is never executed, it's just information

But if I give a integral type I can do

int X::value=3;

Right, so this means that this is executed to associate the memory
location of value to 3
There is a difference in map implementation I guess, but my knowledge
is not that sharp.
 
J

Jim Langston

Thanks, but still not clear what is exactly "know".

It is already empty so that I would like to fill that out.
Code outside a function-block is never executed, it's just information

But if I give a integral type I can do

int X::value=3;

.............................
yes, but you can't say

int X::value = foo();

because foo is an executable statement ( a fucntion call ). the =3 is
actually initializing the variable.

You could say that inside a function block, but not outside.
............................

Right, so this means that this is executed to associate the memory
location of value to 3
There is a difference in map implementation I guess, but my knowledge
is not that sharp.
 
D

dasjotre

utab said:
But if I give a integral type I can do

int X::value=3;

Right, so this means that this is executed to associate the memory
location of value to 3

no, it is compiler generated, not run-time executed
There is a difference in map implementation I guess, but my knowledge
is not that sharp.

the only way you could do what you want would be to something like this

class my_static_map
{
public:

my_static_map()
{
map_["try"].insert(std::make_pair("try", 1));
// ... etc ...
}

typedef std::map<std::string, std::map<std::string, int> > map_t;

// pass-through all operations you want to to use from std::map
// interface

map_t::mapped_type& operator[](const map_t::key_type& key)
{
return map_[key];
}

map_t::iterator insert(const map_t::value_type & val)
{
return map_.insert(val);
}

void erase(map_t::iterator w)
{
map_.erase(w);
}

// ... etc ...

private:

map_t map_;
};

// .h
class X
{
private:
static my_static_map word_map;
};

// .cpp
X::word_map;

now this is run-time executed initialization
 
D

David Harmon

On Tue, 19 Dec 2006 08:40:27 -0800 in comp.lang.c++, "Jim Langston"
yes, but you can't say

int X::value = foo();

because foo is an executable statement ( a fucntion call ). the =3 is
actually initializing the variable.

You could say that inside a function block, but not outside.

No, actually you can do exactly that. Complete program,
compiles and runs just fine, follows:

#include <iostream>
int foo()
{
std::cout << "Initialization...\n";
return 42;
}

struct X
{
static int value;
};

int X::value = foo();

int main()
{
std::cout << X::value << '\n';
}
 
D

David Harmon

On 19 Dec 2006 07:52:53 -0800 in comp.lang.c++, "utab"
but I wondered why I could not define and
initiliaze outside the function block. As

word_map["try"].insert(make_pair("try",1));

and the entries outside any of the functions.

The above has the form of an executable statement. You can't have any
executable statements outside of a block; only declarations.

The thing that makes it difficult is that you cannot write a constant of
type std::map<anything> directly (unlike simple arrays of simple types.)
The compiler doesn't know how to build it. You have to take a trip
through the std::map constructor for that to happen.

If you wished, you could write the definition of your static as:

map< string , map<string, int> > X::word_map = X::initial_map();

where X::initial_map() was a static function that returns a big honking
value of the matching std::map<> type, that gets copied to X::word_map.
This would be doing a lot of extra copying during initialization time,
so it's probably not the best choice. I mention it only for the sake of
comparison.

I guess the best choice for you might be to use a "singleton" pattern.
To do that, make X::word_map() a function that returns a reference to
the static map, and call it wherever you access the map. The first time
through, X::word_map() does all the work of building the map; thereafter
it just returns a reference to the existing map. And of course, it can
use all the executable statements it needs to do that, even reading
values from a file or whatever.

By the way, I cannot guess any reason why the value_type of your map is
another map, so I think you are probably making things a heck of a lot
more complicated than you really need to by doing that.
 
U

utab

By the way, I cannot guess any reason why the value_type of your map is
another map, so I think you are probably making things a heck of a lot
more complicated than you really need to by doing that.

It is more clear now.
Actually I have a structure like the one below

lets say, f stands for fields(strings) and each row is determined by f1
so that it represents another field. But in the mean time I would like
a structure like (since f1 determines the properties)

f1 - > <string , int>

fid :1 2 3 4 5 6 7 8

f1 f2 f3 f4 f5 f6 f7 f8

fid:field id

You are right this was a class that I designed last year but now I see
a lot of flaws in that. So it has to be designed by more attention.
 
D

David Harmon

On 19 Dec 2006 10:41:45 -0800 in comp.lang.c++, "utab"
lets say, f stands for fields(strings) and each row is determined by f1
so that it represents another field. But in the mean time I would like
a structure like (since f1 determines the properties)

f1 - > <string , int>

That is getting simple enough that the compiler can do a greater part of
the work at compile time (however, still leaving plenty for run time, so
maybe not efficient enough for you. But convenient.)
Using the "two iterators" std::map constructor:


#include <iostream>
#include <map>
#include <string>
using namespace std;

typedef std::pair<std::string, int> init;
const init init_map[] = {
init("f1", 1), init("f2", 2), init("f3", 3)
};
const int init_count = sizeof(init_map)/sizeof(init_map[0]);

std::map<string,int> word_map(init_map, init_map+init_count);

int main()
{
std::cout << word_map["f2"] << '\n';
}
 

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,816
Messages
2,569,715
Members
45,503
Latest member
TraceyP38

Latest Threads

Top