Problem using STL list and map objects as static member variables

B

Bit byte

I am writing a small parser object. I need to store keywords etc in
lsts. Because this data is to be shared by all instances of my parser
class, I have declared the variable as class variables (i.e. statics).

//declarations in parser class (private section)
static list<string> m_keywords, m_symbols_used;
static map<string, myParser::FuncData> m_mapped_funcs ;

I have initialization code like this:

m_symbols_used.clear();

//loadup keywords
m_keywords.clear()
m_keywords.push_back(ABC) ;
m_keywords.push_back(CDE) ;

...

I obviously can't place this in the constructor since they are statics -
(actually, I tried but I had linkage errors). Any ideas as to how to
initialize these variales ?
 
V

Victor Bazarov

Bit said:
I am writing a small parser object. I need to store keywords etc in
lsts. Because this data is to be shared by all instances of my parser
class, I have declared the variable as class variables (i.e. statics).

//declarations in parser class (private section)
static list<string> m_keywords, m_symbols_used;
static map<string, myParser::FuncData> m_mapped_funcs ;

I have initialization code like this:

m_symbols_used.clear();

//loadup keywords
m_keywords.clear()
m_keywords.push_back(ABC) ;
m_keywords.push_back(CDE) ;

...

I obviously can't place this in the constructor since they are
statics - (actually, I tried but I had linkage errors). Any ideas as
to how to initialize these variales ?

What you usually do is have a global dummy variable of type 'int' or any
other, and initialise it from a function, inside which you will put your
class-wide member manipulation.

V
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Bit said:
I am writing a small parser object. I need to store keywords etc in
lsts. Because this data is to be shared by all instances of my parser
class, I have declared the variable as class variables (i.e. statics).

//declarations in parser class (private section)
static list<string> m_keywords, m_symbols_used;
static map<string, myParser::FuncData> m_mapped_funcs ;

I have initialization code like this:

m_symbols_used.clear();

//loadup keywords
m_keywords.clear()
m_keywords.push_back(ABC) ;
m_keywords.push_back(CDE) ;

...

I obviously can't place this in the constructor since they are statics -
(actually, I tried but I had linkage errors). Any ideas as to how to
initialize these variales ?

A simple way to simulate an static constructor is:

class A {
class InitClass {
InitClass ();
};
static InitiClass initiclass;
friend class InitClass;
};

A:InitClass A:initiclass;

A::InitClass::InitClass ()
{
// Anyway you need no initialize statics of A
}

Some verbosity, but no additional data member required. And you can put some
static members inside InitClass to make the code cleaner.
 
B

Bit byte

Bit said:
I am writing a small parser object. I need to store keywords etc in
lsts. Because this data is to be shared by all instances of my parser
class, I have declared the variable as class variables (i.e. statics).

//declarations in parser class (private section)
static list<string> m_keywords, m_symbols_used;
static map<string, myParser::FuncData> m_mapped_funcs ;

I have initialization code like this:

m_symbols_used.clear();

//loadup keywords
m_keywords.clear()
m_keywords.push_back(ABC) ;
m_keywords.push_back(CDE) ;

...

I obviously can't place this in the constructor since they are statics -
(actually, I tried but I had linkage errors). Any ideas as to how to
initialize these variales ?


Hmmm, judging by the feedback I've had so far, I'd probably make my
self clearer:

This is an (abridged version of) my class.

class MyParser
{
public:
MyParser();
MyParser(const string);
MyParser(const MyParser&);
MyParser& operator= (const MyParser&);

private:
typedef struct { string name, int argc } FuncData ;

static list<string> m_keywords ;
static map<string,FuncData> m_mapped_funcs ;
};

I wanted to know how can I initialize (i.e. populate) the static (and
private) member variables ?
 
V

Victor Bazarov

Bit said:
Hmmm, judging by the feedback I've had so far, I'd probably make my
self clearer:

This is an (abridged version of) my class.

class MyParser
{
public:
MyParser();
MyParser(const string);
MyParser(const MyParser&);
MyParser& operator= (const MyParser&);

private:
typedef struct { string name, int argc } FuncData ;

static list<string> m_keywords ;
static map<string,FuncData> m_mapped_funcs ;

Add here:
static int keyword_and_funcs_init_function();
static int dummy;
};

I wanted to know how can I initialize (i.e. populate) the static (and
private) member variables ?

Where you define the 'm_keywords', right after them, add:

int MyParser::dummy = MyParser::keyword_and_funcs_init_function();

/* static */ int MyParser::keyword_and_funcs_init_function()
{
/* do your stuffing of 'm_keywords' and 'm_mapped_funcs' here */
return 42;
}

V
 
M

Mark P

Bit said:
Hmmm, judging by the feedback I've had so far, I'd probably make my
self clearer:

This is an (abridged version of) my class.

class MyParser
{
public:
MyParser();
MyParser(const string);
MyParser(const MyParser&);
MyParser& operator= (const MyParser&);

private:
typedef struct { string name, int argc } FuncData ;

static list<string> m_keywords ;
static map<string,FuncData> m_mapped_funcs ;
};

I wanted to know how can I initialize (i.e. populate) the static (and
private) member variables ?

What was wrong with Victor's suggestion? Here is an example
illustrating his idea which seems to be essentially what you need:

---> begin code

#include <list>
#include <iostream>
#include <iterator>
#include <algorithm>

using namespace std;

struct A
{
static list<int> li;
static int initializeLi ();
};

int A::initializeLi ()
{
li.push_back(0);
li.push_back(1);
li.push_back(2);
return 0;
}

list<int> A::li;
const int throwAway = A::initializeLi();

int main ()
{
copy(A::li.begin( ), A::li.end(), ostream_iterator<int>(cout,"\n"));
}

---> end code
 
F

Frederick Gotham

Mark P posted:
struct A
{
static list<int> li;
static int initializeLi ();
};

int A::initializeLi ()
{
li.push_back(0);
li.push_back(1);
li.push_back(2);
return 0;
}

list<int> A::li;
const int throwAway = A::initializeLi();


I'd probably use a "static constructor":

#include <list>

struct A {

std::list<int> static li;

private:

struct StaticConstructor {

StaticConstructor()
{
A::li.push_back(0);
A::li.push_back(1);
A::li.push_back(2);
}

} const static stctr;

};


std::list<int> A::li;

int main() {}
 
V

Victor Bazarov

Bit said:
Victor Bazarov wrote:
[..]
Where you define the 'm_keywords', right after them, [..]

Thanks Victor, I understand now. However, when I apply the
modifications you sugested, I'm still getting linkage errors:

error LNK2001: unresolved external symbol "private: static class
std::list<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >,class
std::allocator<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > > >
MyParser::m_keywords"
(?m_keywords@MyParser@@0V?$list@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@A)

I can't imagine why I'm getting this linkage error - any ideas ? (I've
run out of ideas)

Read above. WHERE you *define* the 'm_keywords'... So where is it?
Did you forget to *define* 'm_keywords'?

V
 
B

Bit byte

Victor said:
Add here:
static int keyword_and_funcs_init_function();
static int dummy;




Where you define the 'm_keywords', right after them, add:

int MyParser::dummy = MyParser::keyword_and_funcs_init_function();

/* static */ int MyParser::keyword_and_funcs_init_function()
{
/* do your stuffing of 'm_keywords' and 'm_mapped_funcs' here */
return 42;
}

V

Thanks Victor, I understand now. However, when I apply the modifications
you sugested, I'm still getting linkage errors:

error LNK2001: unresolved external symbol "private: static class
std::list<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >,class
std::allocator<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > > >
MyParser::m_keywords"
(?m_keywords@MyParser@@0V?$list@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@A)

I can't imagine why I'm getting this linkage error - any ideas ? (I've
run out of ideas)
 
B

Bit byte

Victor said:
Add here:
static int keyword_and_funcs_init_function();
static int dummy;




Where you define the 'm_keywords', right after them, add:

int MyParser::dummy = MyParser::keyword_and_funcs_init_function();

/* static */ int MyParser::keyword_and_funcs_init_function()
{
/* do your stuffing of 'm_keywords' and 'm_mapped_funcs' here */
return 42;
}

V

Thanks Victor, I understand now. However, when I apply the modifications
you sugested, I'm still getting linkage errors:

error LNK2001: unresolved external symbol "private: static class
std::list<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >,class
std::allocator<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > > >
MyParser::m_keywords"
(?m_keywords@MyParser@@0V?$list@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@A)

I can't imagine why I'm getting this linkage error - any ideas ? (I've
run out of ideas)
 
B

Bit Byte

Victor said:
Bit said:
Victor Bazarov wrote:
[..]
Where you define the 'm_keywords', right after them, [..]

Thanks Victor, I understand now. However, when I apply the
modifications you sugested, I'm still getting linkage errors:

error LNK2001: unresolved external symbol "private: static class
std::list<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >,class
std::allocator<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > > >
MyParser::m_keywords"
(?m_keywords@MyParser@@0V?$list@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@A)

I can't imagine why I'm getting this linkage error - any ideas ? (I've
run out of ideas)


Read above. WHERE you *define* the 'm_keywords'... So where is it?
Did you forget to *define* 'm_keywords'?

V

Yes, my fault. Thanks for the clarification. Builds fine now.
 
M

mlimber

Bit said:
I am writing a small parser object. I need to store keywords etc in
lsts. Because this data is to be shared by all instances of my parser
class, I have declared the variable as class variables (i.e. statics).

//declarations in parser class (private section)
static list<string> m_keywords, m_symbols_used;
static map<string, myParser::FuncData> m_mapped_funcs ;

I have initialization code like this:

m_symbols_used.clear();

//loadup keywords
m_keywords.clear()
m_keywords.push_back(ABC) ;
m_keywords.push_back(CDE) ;

...

I obviously can't place this in the constructor since they are statics -
(actually, I tried but I had linkage errors). Any ideas as to how to
initialize these variales ?

Use an initializer helper class:

class A
{
public:
// ...
private:
static const std::map<int,const char*> map_;
};

Then in your .cpp file:

namespace // anonymous
{
template<class Key, class Value>
class MapInitializer
{
std::map<Key,Value> m_;
public:
operator std::map<Key,Value>() const { return m_; }

MapInitializer& Add( const Key& k, const Value& v )
{
m_[k] = v;
return *this;
}
};
}

const std::map<int,const char*> A::map_
= MapInitializer<int,const char*>()
.Add( 10, "Msg 1" )
.Add( 20, "Msg 2" )
.Add( 30, "Msg 3" );

Cheers! --M
 
L

Lars Tetzlaff

Bit said:
I am writing a small parser object. I need to store keywords etc in
lsts. Because this data is to be shared by all instances of my parser
class, I have declared the variable as class variables (i.e. statics).

//declarations in parser class (private section)
static list<string> m_keywords, m_symbols_used;
static map<string, myParser::FuncData> m_mapped_funcs ;

I have initialization code like this:

m_symbols_used.clear();

//loadup keywords
m_keywords.clear()
m_keywords.push_back(ABC) ;
m_keywords.push_back(CDE) ;

...

I obviously can't place this in the constructor since they are statics -
(actually, I tried but I had linkage errors). Any ideas as to how to
initialize these variales ?

#include <list>
#include <string>
#include <map>

class Parser
{
private:
static const class KeyWords : public std::list<std::string>
{
public:
KeyWords()
{
push_back( "ABC" );
push_back( "CDE" );
}
} m_keywords; // initialiszed with keywords

struct FuncData
{
std::string name;
int argc;
};

static std::map<std::string, FuncData> m_mapped_funcs ; // initilized
emtpty
static std::list<std::string> m_symbols_used;
};

int main()
{
Parser aParser;
}
 
V

Victor Bazarov

Lars said:
[...]
#include <list>
#include <string>
#include <map>

class Parser
{
private:
static const class KeyWords : public std::list<std::string>
{
public:
KeyWords()
{
push_back( "ABC" );
push_back( "CDE" );
}
} m_keywords; // initialiszed with keywords

This static data member doesn't seem to have been defined anywhere...
struct FuncData
{
std::string name;
int argc;
};

static std::map<std::string, FuncData> m_mapped_funcs ; //
initilized emtpty
static std::list<std::string> m_symbols_used;

Neither are those two static data members...
};

int main()
{
Parser aParser;
}

V
 
L

Lars Tetzlaff

Victor said:
Lars said:
[...]
#include <list>
#include <string>
#include <map>

class Parser
{
private:
static const class KeyWords : public std::list<std::string>
{
public:
KeyWords()
{
push_back( "ABC" );
push_back( "CDE" );
}
} m_keywords; // initialiszed with keywords

This static data member doesn't seem to have been defined anywhere...

It's not used so it's not missing ;)
Neither are those two static data members...


V

add

const Parser::KeyWords Parser::m_keywords;
std::map<std::string, Parser::FuncData> Parser::m_mapped_funcs ;
std::list<std::string> Parser::m_symbols_used;

wherever (Parser.cpp?) you want if you need them

Lars
 

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,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top