C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

how to access enum fields?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Dennis Schulz
Guest





PostPosted: Sun Jan 16, 2005 11:21 am    Post subject: how to access enum fields? Reply with quote



Hi, I have the following problem:
I want to find out the number of the month from given string.
I defined 12 constants as a enum type num:

enum num{Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8,
Sep=9, Okt=10, Nov=11, Dec=12};

now I want to access the number of the month

This is working:
num n = Dec;

There is an error:
num n = static_cast<num>(MyString);

How can I convert it to a num type??

Thank you

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Patrick Leslie Polzer
Guest





PostPosted: Mon Jan 17, 2005 12:34 am    Post subject: Re: how to access enum fields? Reply with quote



Dennis Schulz wrote:
Quote:
enum num{Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8,
Sep=9, Okt=10, Nov=11, Dec=12};
[...]
There is an error:
num n = static_cast<num>(MyString);

How can I convert it to a num type??
Set up a conversion table.


Leslie

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Larry Evans
Guest





PostPosted: Mon Jan 17, 2005 12:36 am    Post subject: Re: how to access enum fields? Reply with quote



On 01/16/2005 04:21 AM, Dennis Schulz wrote:
[snip]
Quote:
There is an error:
num n = static_cast<num>(MyString);

How can I convert it to a num type??
First convert MyString to a number, possibly using

MyString.str() or something that returns a char* and
then use c's library function, atoi (I think that's right).
Alternately, convert the c* to a std::istrstream and extract
( i.e. something like a_istr>>a_int;) then do the
static_cast. I haven't tested it though.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Maxim Yegorushkin
Guest





PostPosted: Mon Jan 17, 2005 8:00 pm    Post subject: Re: how to access enum fields? Reply with quote

On 16 Jan 2005 06:21:44 -0500, Dennis Schulz <d.schulz81 (AT) gmx (DOT) net> wrote:

Quote:
Hi, I have the following problem:
I want to find out the number of the month from given string.
I defined 12 constants as a enum type num:

enum num{Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8,
Sep=9, Okt=10, Nov=11, Dec=12};

now I want to access the number of the month

This is working:
num n = Dec;

There is an error:
num n = static_cast<num>(MyString);

How can I convert it to a num type??

Basically, you have to somehow map each month name to your enum. It could
be as simple as building an array of month names and then searching it
linearly:

char const* const month_names = { "Jan", "Feb", ..., "Dec", 0 };

int month_index(char const* month)
{
char const* const* p = month_names;
for(; *p; ++p)
if(!strcmp(month, *p))
break;
return *p ? p - month_names : -1;
}

(There are more powerful techniques and tools you can use for mapping a
string to an integer, like binary and ternary trees, hashing.)

Using the array and the function you can convert your enums to strings and
back:

char const* enum_to_str(num n)
{
return month_names[n - 1];
}

num str_to_enum(char const* month)
{
int const index = month_index(month);
return -1 != index ? static_cast<num>(index + 1) : throw
std::logic_error("bad month name");
}

Quote:
num n = static_cast<num>(MyString);

You can static_cast<> syntax to convert a string to your enum only if your
string class has a conversion operator to your enum (that is,
MyString::operator num()), because enum's can't have constructors which
static_cast<> could use. Alternatively, you can define a class for
representing months with a constructor that takes a string, something
along the lines:

class month
{
private:
num m_;
public:
month(num m) : m_(m) {}
month(char const* m) : m_(str_to_enum(m)) {}
};

And then:

month m = static_cast<month>(MyString.c_str());

--
Maxim Yegorushkin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Abhishek Pandey
Guest





PostPosted: Mon Jan 17, 2005 8:09 pm    Post subject: Re: how to access enum fields? Reply with quote


"Dennis Schulz" <d.schulz81 (AT) gmx (DOT) net> wrote

Quote:
Hi, I have the following problem:
I want to find out the number of the month from given string.
I defined 12 constants as a enum type num:

enum num{Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8,
Sep=9, Okt=10, Nov=11, Dec=12};

now I want to access the number of the month

This is working:
num n = Dec;

There is an error:
num n = static_cast<num>(MyString);

MyString is a character string e.g. "Feb" while Feb is a enum constant whose
value is 2.
You can not straightaway cast the string into integer in the way you are
trying to do.
You have to write some logic for conversion yourself.

Thanks
Abhishek

Quote:
How can I convert it to a num type??

Thank you

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Jan 17, 2005 8:16 pm    Post subject: Re: how to access enum fields? Reply with quote

Dennis Schulz wrote:
Quote:
Hi, I have the following problem:
I want to find out the number of the month from given string.
I defined 12 constants as a enum type num:

enum num{Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8,
Sep=9, Okt=10, Nov=11, Dec=12};

now I want to access the number of the month

This is working:
num n = Dec;

There is an error:
num n = static_cast<num>(MyString);

How can I convert it to a num type??

Use an std::map< std::string, num >. To initialize
the map, use something like the following:

Quote:
typedef std::map< std::string, num
Map ;
struct Init
{
char const* name ;
enum value ;
operator Map::value_type() const
{
return Map::value_type( std::string( name ), value )
;
}
} ;
static Init const init[] =
{
{ "Jan", Jan },
{ "Feb", Feb },
// ...
} ;
Map const enumMap( init, init + 12 ) ;

Alternatively, if you want to allow abbreviations, full names,
caps and small letters, etc., you might want to write your own
comparator, and just use std::find on a C style array. Since
the table is unlikely to grow beyond twelve entries, the
performance using a linear search should not be a problem.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jonathan Bartlett
Guest





PostPosted: Tue Jan 18, 2005 11:06 pm    Post subject: Re: how to access enum fields? Reply with quote

Dennis Schulz wrote:
Quote:
Hi, I have the following problem:
I want to find out the number of the month from given string.
I defined 12 constants as a enum type num:

enum num{Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8,
Sep=9, Okt=10, Nov=11, Dec=12};

now I want to access the number of the month

This is working:
num n = Dec;

There is an error:
num n = static_cast<num>(MyString);

How can I convert it to a num type??

You can't directly. Enums are NOT strings, they are symbols, which are
thrown away after compilation. Similarly, if I have a string "A" and a
variable A I can't convert from one to the other.

Therefore, you need to set up a set of if statements to check the string
and convert to the number.

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
brablc
Guest





PostPosted: Wed Jan 19, 2005 11:49 pm    Post subject: Translation table (Was: how to access enum fields?) Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:

Use an std::map< std::string, num >. To initialize
the map, use something like the following:
...

This sounds like a good and general way to initialize a translation
table. So with a small change I get code stated bellow. But I have two
problems:

1) I have to specify number of elements in the the map constructor.
2) Access to the values via operator[] does not work when the map is
const.

template<class Value> struct MapInit
{
const char * key;
Value value ;
typedef typename
std::map< std::string, Value >::value_type value_type;
operator value_type() const {
return value_type( std::string( key ), value );
}
};

static MapInit<std::string> const initTradeType[] =
{
{ "N", "New" },
{ "C", "Cancel" }
} ;

std::map<std::string, std::string>
tradeTypeMap( initTradeType, initTradeType+2 ) ;

Best regards,
Ondrej

---
Family Homepage: http://brablc.com
Bookmark Server: http://sitebar.org (GPL)


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Thu Jan 20, 2005 6:14 pm    Post subject: Re: Translation table (Was: how to access enum fields?) Reply with quote

brablc wrote:
Quote:
kanze (AT) gabi-soft (DOT) fr wrote:

Use an std::map< std::string, num >. To initialize
the map, use something like the following:
...

This sounds like a good and general way to initialize a
translation table. So with a small change I get code stated
bellow. But I have two problems:

1) I have to specify number of elements in the the map constructor.

Not really, see below.

Quote:
2) Access to the values via operator[] does not work when the
map is const.

So don't use the [] operator.

The real question is what do you do if you don't find the
entry. I usually wrap such classes in a higher level class,
whose [] operator returns a pointer to the element (and not a
copy), or a null pointer if the element isn't found; there are
also cases where not finding the element results in an assertion
failure.

Quote:
template<class Value> struct MapInit
{
const char * key;
Value value ;
typedef typename
std::map< std::string, Value >::value_type value_type;
operator value_type() const {
return value_type( std::string( key ), value );
}
};

static MapInit<std::string> const initTradeType[] =
{
{ "N", "New" },
{ "C", "Cancel" }
} ;

Careful. There might be order of initialization issues here,
since the array is dynamically initialized. I tend to only use
PODs in my Init classes. In this case, for example, I would
declare MapInit to contain two char const*. (Of course, this
somewhat limits the use of a template for them. And typically,
the definition of the initialization table will be in the same
compilation unit as the map, which means that order is
guaranteed.)

Quote:
static size_t iniTradeCount
= sizeof( IinitTradeType ) /sizeof( initTradeType[ 0 ] ) ;

is the classical, C-style solution. I usually use the
pseudo-standard global begin and end functions:

Quote:
template< typename T, size_t N
T const*
begin( T const (&array)[ N ] )
{
return array ;
}

template< typename T, size_t N
T const*
end( T const (&array)[ N ] )
{
return array + N ;
}

std::map tradeTypeMap( initTradeType, initTradeType+2 ) ;

std::map< std::string, std::string
tradeTypeMap( begin( initTradeType ),
end( initTradeType ) ) ;

With both this and the classical C-like solution, the compiler
does the counting, not you.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Allan W
Guest





PostPosted: Thu Jan 20, 2005 8:08 pm    Post subject: Linux Assembly Language? Reply with quote

Jonathan Bartlett wrote:
Quote:
Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017

Does that make sense? "Linux assembly language?"

I suppose you mean the assembly language of the Intel 80386 (or
possibly you assume a 486 or a Pentium), and Linux system calls.
Although I've heard that Linux ports are available for 680x0,
DEC Alpha, SPARCs, and others... hard to see how any true "assembly
language" could run on all of these platforms.

Then again, I'm not a Linux guru. Is there actually an assembly
language for Linux, different in some significant way from Intel
assembly language?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jonathan Bartlett
Guest





PostPosted: Fri Jan 21, 2005 10:28 am    Post subject: Re: Linux Assembly Language? Reply with quote

Quote:
Does that make sense? "Linux assembly language?"


The book is for people new to programming. Saying "assembly language
for 80386 and higher CPUs using Linux kernel system calls" would not
make sense. Since we use Linux on its most common architecture, and use
Linux-specific system calls, and use the AT&T syntax, then, yes, "Linux
assembly language" makes sense. I have enough trouble trying to
convince people that there are more processors in the world than those
that are Intel-compatible that I felt making the distinction on the
cover of the book would not be helpful. If you know enough about
computers and Linux to be running Linux on a different platform, you
probably have enough intelligence to guess what architecture I'm talking
about or to ask someone. If you don't, the distinction is just confusing.

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ondrej Brablc
Guest





PostPosted: Sat Jan 22, 2005 4:48 am    Post subject: Re: Translation table (Was: how to access enum fields?) Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:
brablc wrote:

This sounds like a good and general way to initialize a
translation table. So with a small change I get code stated
bellow. But I have two problems:

1) I have to specify number of elements in the the map constructor.

Not really, see below.

2) Access to the values via operator[] does not work when the
map is const.

So don't use the [] operator.

Thank you for your hints, I think I have an implementation that is good
enough (plese let me know on my email if the code is too long for this
group).

Quote:
#include <string
#include #include #include
/* INTERFACE */

template< class Value> class TranslationMap
{
public:
typedef typename std::map< std::string, Value > valueMap;

struct Init
{
const char * key;
Value value;
typedef typename valueMap::value_type value_type;
operator value_type() const
{
return value_type( std::string( key ), value );
}
};

template< typename T, size_t N
TranslationMap(std::string aTableName, T const (&array)[ N
]):
mTableName(aTableName), mMap(array, array+N)
{
}

template< class InputIterator
TranslationMap(std::string aTableName,
InputIterator first, InputIterator last):
mTableName(aTableName), mMap(first, last)
{
}

const Value & operator[]( std::string key) const
throw(std::domain_error)
{
typedef typename valueMap::const_iterator const_iterator;
const_iterator found = mMap.find(key);
if (found == mMap.end())
{
throw std::domain_error( mTableName+": Unknown key
["+key+"]" );
}
return (*found).second;
}

private:
std::string mTableName;
valueMap mMap;
};

/* INITIALIZATION */

static TranslationMap {
{ "Jan", 1 },
{ "Feb", 2 },
{ "Mrz", 3 },
{ "Apr", 4 },
{ "Mai", 5 },
{ "Jun", 6 },
{ "Jul", 7 },
{ "Aug", 8 },
{ "Sep", 9 },
{ "Okt", 10 },
{ "Nov", 11 },
{ "Dez", 12 },
};

static const TranslationMap<int> MONTHS( "MONTHS", initMonths );

/* USAGE */

int main()
{
try
{
std::cout << "Jan=" << MONTHS["Jan"] << std::endl;
std::cout << "Mar=" << MONTHS["Mar"] << std::endl;
}
catch ( std::exception & e)
{
std::cerr << "Exception has occured: " << e.what()
std::endl;
}
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Jan 24, 2005 8:17 pm    Post subject: Re: Translation table (Was: how to access enum fields?) Reply with quote

Ondrej Brablc wrote:

Quote:
Thank you for your hints, I think I have an implementation
that is good enough.

Seems pretty good to me.

In my own code, the map is a singleton. My own code was
written long before templates existed, and uses small lex/yacc
program to generate the code, including the tables. The template
is probably preferable, but then you'd need a function for
initializing the tables (called from the constructor, and
generated by the lex/yacc code). So the constructor would look
something like:

template< typename Value >
TranslationMap::TranslationMap()
{
extern void initializeTranslationMap( ValueMap& ) ;
initializeTranslationMap( mMap ) ;
}

Where, of course, initializeTranslationMap is the code generated
by lex/yacc. (Note that even if the actual object is const, it
doesn't become const until the constructor has terminated. Note
too that by passing it the mMap parameter, we've made it
dependent. And that I can't find any reasonable place to put
the extern declaration but in the function itself.)

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.