how to initialize a class static member variable of composite type

N

Nan Li

Hello,
I got stuck in a situation I think many of you must have already
experienced. I want to have a simple lookup map inside my class. All
the instances share that map. The code is as follows.

class A
{
private:
static std::map<int,std::string> someMap;
public:
......
};

But I don't know how I can initialize this map properly.


Thanks,
Nan
 
W

Wanderley Caloni

You just need a start condition and verify it in the construction of
every instance of class A:

A::A()
{
if( ! someMapStarted )
{
startSomeMap();
someMapStarted = true;
}
}

Needles to say that this variable need to be static =)
 
V

Victor Bazarov

Nan said:
Hello,
I got stuck in a situation I think many of you must have already
experienced. I want to have a simple lookup map inside my class. All
the instances share that map. The code is as follows.

class A
{
private:
static std::map<int,std::string> someMap;
public:
......
};

But I don't know how I can initialize this map properly.

What would you like to have in that map? There are several constructors
in the 'map' template. One takes the comparator and the allocator (and it
is also the default constructor), another takes two iterators, yet another
is a copy-constructor. Do you want some information to be put into that
shared map at the time of construction?

std::map<int,std::string> A::someMap; // default-initialisation

std::map<int,std::string> A::someMap(iter1,iter2); // initialisation
// from 2 iterators

(to use that the iterators need to dereference to a type that can be
inserted into your map, namely, std::pair<int,std::string>).

V
 
N

Neil Cerutti

Hello,

I got stuck in a situation I think many of you must have
already experienced. I want to have a simple lookup map inside
my class. All the instances share that map. The code is as
follows.

class A
{
private:
static std::map<int,std::string> someMap;
public:
......
};

But I don't know how I can initialize this map properly.

Here's one way. Put the map inside a static function.

class A
{
static const std::map<int, std::string>& get_map()
{
static std::map<int, std::string> the_map;
if (the_map.size() == 0) {
/* Initialize the_map */
}
return the_map;
}
/* ... */
}

If it's possible for an initialized map to have size 0, then
you'll need to use a flag instead.
 
N

Nan Li

Victor said:
What would you like to have in that map? There are several constructors
in the 'map' template. One takes the comparator and the allocator (and it
is also the default constructor), another takes two iterators, yet another
is a copy-constructor. Do you want some information to be put into that
shared map at the time of construction?

std::map<int,std::string> A::someMap; // default-initialisation

std::map<int,std::string> A::someMap(iter1,iter2); // initialisation
// from 2 iterators

(to use that the iterators need to dereference to a type that can be
inserted into your map, namely, std::pair<int,std::string>).

V

Thanks a lot. Following your advice, I came up with the following code
and it works fine.

using namespace std;


typedef pair<int,string> IntStringPair;


class A
{
public:
static const IntStringPair MAPPINGS[];
static const map<int, string> someMap;
};


const IntStringPair A::MAPPINGS[] = { IntStringPair(1, "foo" ),
IntStringPair(2, "bar")
};


const std::map<int, string> A::someMap( MAPPINGS,
MAPPINGS + sizeof( MAPPINGS ) /
sizeof( MAPPINGS[0] ) );
 
J

John Harrison

Nan said:
Hello,
I got stuck in a situation I think many of you must have already
experienced. I want to have a simple lookup map inside my class. All
the instances share that map. The code is as follows.

class A
{
private:
static std::map<int,std::string> someMap;
public:
......
};

But I don't know how I can initialize this map properly.


Thanks,
Nan

If you don't mind the one-off cost of copying a map there's nothing
wrong with the obvious

class A
{
static std::map<int, std::string> someMap;
};

....

std::map<int, std::string> A::someMap = some_function();

Whatever some_function returns will initialise SomeMap.

john
 
N

Nan Li

John said:
If you don't mind the one-off cost of copying a map there's nothing
wrong with the obvious

class A
{
static std::map<int, std::string> someMap;
};

...

std::map<int, std::string> A::someMap = some_function();

Whatever some_function returns will initialise SomeMap.

john

This is a good idea. I can do something like below. The actual map is
inside the function( see Neil's post )

class A
{
private:
static const map<int, string>& someMap;
static const map<int,string>& initSomeMap();
};


const map<int,string>& A::initSomeMap()
{
static map<int, string> m;
m[1] = "foo";
m[2] = "bar";
return m;
};

const map<int, string>& A::someMap = A::initSomeMap() ;
 
N

Nan Li

Wanderley said:
You just need a start condition and verify it in the construction of
every instance of class A:

A::A()
{
if( ! someMapStarted )
{
startSomeMap();
someMapStarted = true;
}
}

Needles to say that this variable need to be static =)

Thanks. But in this particular case, I actually don't want to do lazy
loading, and I don't want to have a check every time an object is
created.
 

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,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top